Commit 6f9d8a14 authored by Marc Celani's avatar Marc Celani Committed by Facebook Github Bot

Optimize MicroSpinLock for the unlocked case

Summary:
MicroSpinLock was doing a non-relaxed load before cas, which seems odd because typically we expect spin locks to be unlocked. This diff flips the order and assumes the lock is unlocked before doing a load-loop.

While the benchmark results for SmallLocksBenchmark are a little mixed, the results in a more real world use case in stats/DigestBuilderBenchmark show that this is a real winner.

Reviewed By: djwatson

Differential Revision: D7828158

fbshipit-source-id: e195b9739ce931a67a39ffb9715a228aef59f6bc
parent 2378b40e
...@@ -110,19 +110,19 @@ BENCHMARK_RELATIVE_NAMED_PARAM_MULTI(append, 10000x32, 10000, 32) ...@@ -110,19 +110,19 @@ BENCHMARK_RELATIVE_NAMED_PARAM_MULTI(append, 10000x32, 10000, 32)
* ============================================================================ * ============================================================================
* folly/stats/test/DigestBuilderBenchmark.cpp relative time/iter iters/s * folly/stats/test/DigestBuilderBenchmark.cpp relative time/iter iters/s
* ============================================================================ * ============================================================================
* append(1000x1) 43.84ns 22.81M * append(1000x1) 39.55ns 25.28M
* append(1000x2) 97.54% 44.95ns 22.25M * append(1000x2) 97.52% 40.56ns 24.66M
* append(1000x4) 96.14% 45.60ns 21.93M * append(1000x4) 95.11% 41.59ns 24.05M
* append(1000x8) 93.31% 46.99ns 21.28M * append(1000x8) 92.80% 42.62ns 23.46M
* append(1000x16) 44.73% 98.02ns 10.20M * append(1000x16) 49.93% 79.21ns 12.62M
* append(1000x32) 34.43% 127.33ns 7.85M * append(1000x32) 35.70% 110.78ns 9.03M
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* append(10000x1) 44.85ns 22.29M * append(10000x1) 41.01ns 24.38M
* append(10000x2) 97.39% 46.06ns 21.71M * append(10000x2) 98.91% 41.46ns 24.12M
* append(10000x4) 94.25% 47.59ns 21.01M * append(10000x4) 94.80% 43.26ns 23.12M
* append(10000x8) 93.20% 48.13ns 20.78M * append(10000x8) 92.04% 44.56ns 22.44M
* append(10000x16) 50.75% 88.39ns 11.31M * append(10000x16) 49.19% 83.37ns 12.00M
* append(10000x32) 34.10% 131.52ns 7.60M * append(10000x32) 33.38% 122.84ns 8.14M
* ============================================================================ * ============================================================================
*/ */
......
...@@ -79,11 +79,11 @@ struct MicroSpinLock { ...@@ -79,11 +79,11 @@ struct MicroSpinLock {
void lock() { void lock() {
detail::Sleeper sleeper; detail::Sleeper sleeper;
do { while (!try_lock()) {
while (payload()->load() != FREE) { do {
sleeper.wait(); sleeper.wait();
} } while (payload()->load(std::memory_order_relaxed) == LOCKED);
} while (!try_lock()); }
assert(payload()->load() == LOCKED); assert(payload()->load() == LOCKED);
} }
......
...@@ -368,60 +368,60 @@ int main(int argc, char** argv) { ...@@ -368,60 +368,60 @@ int main(int argc, char** argv) {
locks_benchmark --bm_min_iters=1000000 locks_benchmark --bm_min_iters=1000000
std::mutex: std::mutex:
Sum: 2879853 Mean: 89995 stddev: 1906 Sum: 2838030 Mean: 88688 stddev: 2067
Lock time stats in us: mean 11 stddev 1491 max 12271 Lock time stats in us: mean 11 stddev 1513 max 21167
InitLock<folly::MicroSpinLock>: InitLock<folly::MicroSpinLock>:
Sum: 3148551 Mean: 98392 stddev: 74339 Sum: 3223948 Mean: 100748 stddev: 76317
Lock time stats in us: mean 19 stddev 1364 max 180125 Lock time stats in us: mean 18 stddev 1332 max 302752
InitLock<folly::PicoSpinLock<uint16_t>>: InitLock<folly::PicoSpinLock<uint16_t>>:
Sum: 1137238 Mean: 35538 stddev: 28156 Sum: 1145725 Mean: 35803 stddev: 20142
Lock time stats in us: mean 54 stddev 3776 max 322180 Lock time stats in us: mean 53 stddev 3748 max 276859
folly::MicroLock: folly::MicroLock:
Sum: 1897729 Mean: 59304 stddev: 25571 Sum: 1935310 Mean: 60478 stddev: 32693
Lock time stats in us: mean 30 stddev 2263 max 23898 Lock time stats in us: mean 29 stddev 2219 max 22368
============================================================================ ============================================================================
folly/synchronization/test/SmallLocksBenchmark.cpprelative time/iter iters/s folly/synchronization/test/SmallLocksBenchmark.cpprelative time/iter iters/s
============================================================================ ============================================================================
StdMutexUncontendedBenchmark 27.15ns 36.83M StdMutexUncontendedBenchmark 27.15ns 36.83M
MicroSpinLockUncontendedBenchmark 9.70ns 103.11M MicroSpinLockUncontendedBenchmark 10.09ns 99.11M
PicoSpinLockUncontendedBenchmark 15.19ns 65.83M PicoSpinLockUncontendedBenchmark 15.15ns 66.02M
MicroLockUncontendedBenchmark 26.73ns 37.41M MicroLockUncontendedBenchmark 26.71ns 37.44M
VirtualFunctionCall 333.36ps 3.00G VirtualFunctionCall 333.37ps 3.00G
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(1thread) 1.07us 931.07K std_mutex(1thread) 856.92ns 1.17M
folly_microspin(1thread) 107.98% 994.71ns 1.01M folly_microspin(1thread) 101.02% 848.25ns 1.18M
folly_picospin(1thread) 104.65% 1.03us 974.35K folly_picospin(1thread) 101.95% 840.52ns 1.19M
folly_microlock(1thread) 127.27% 843.90ns 1.18M folly_microlock(1thread) 98.60% 869.08ns 1.15M
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(2thread) 1.38us 722.80K std_mutex(2thread) 1.34us 744.36K
folly_microspin(2thread) 124.79% 1.11us 901.99K folly_microspin(2thread) 132.73% 1.01us 987.98K
folly_picospin(2thread) 123.67% 1.12us 893.87K folly_picospin(2thread) 125.87% 1.07us 936.94K
folly_microlock(2thread) 123.19% 1.12us 890.42K folly_microlock(2thread) 122.59% 1.10us 912.54K
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(4thread) 2.80us 357.26K std_mutex(4thread) 2.97us 337.23K
folly_microspin(4thread) 79.24% 3.53us 283.10K folly_microspin(4thread) 124.18% 2.39us 418.79K
folly_picospin(4thread) 122.78% 2.28us 438.65K folly_picospin(4thread) 124.57% 2.38us 420.08K
folly_microlock(4thread) 96.59% 2.90us 345.09K folly_microlock(4thread) 86.75% 3.42us 292.56K
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(8thread) 5.49us 182.15K std_mutex(8thread) 6.12us 163.36K
folly_microspin(8thread) 94.14% 5.83us 171.48K folly_microspin(8thread) 96.91% 6.32us 158.30K
folly_picospin(8thread) 64.53% 8.51us 117.55K folly_picospin(8thread) 78.49% 7.80us 128.22K
folly_microlock(8thread) 74.02% 7.42us 134.83K folly_microlock(8thread) 84.30% 7.26us 137.72K
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(16thread) 11.86us 84.30K std_mutex(16thread) 12.14us 82.36K
folly_microspin(16thread) 121.77% 9.74us 102.65K folly_microspin(16thread) 156.31% 7.77us 128.74K
folly_picospin(16thread) 62.15% 19.09us 52.39K folly_picospin(16thread) 55.58% 21.84us 45.78K
folly_microlock(16thread) 65.02% 18.25us 54.81K folly_microlock(16thread) 69.51% 17.47us 57.25K
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(32thread) 22.66us 44.13K std_mutex(32thread) 21.96us 45.54K
folly_microspin(32thread) 116.62% 19.43us 51.46K folly_microspin(32thread) 129.72% 16.93us 59.08K
folly_picospin(32thread) 48.54% 46.69us 21.42K folly_picospin(32thread) 38.35% 57.26us 17.47K
folly_microlock(32thread) 66.88% 33.89us 29.51K folly_microlock(32thread) 68.93% 31.85us 31.39K
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
std_mutex(64thread) 45.13us 22.16K std_mutex(64thread) 40.99us 24.40K
folly_microspin(64thread) 114.88% 39.28us 25.46K folly_microspin(64thread) 98.22% 41.73us 23.97K
folly_picospin(64thread) 38.82% 116.25us 8.60K folly_picospin(64thread) 33.16% 123.61us 8.09K
folly_microlock(64thread) 64.43% 70.05us 14.28K folly_microlock(64thread) 64.89% 63.16us 15.83K
============================================================================ ============================================================================
*/ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment