Skip to content

Commit

Permalink
Implement exponential backoff in spinlock (#2391)
Browse files Browse the repository at this point in the history
Summary:
X-link: facebook/hhvm#9592

Pull Request resolved: #2391

Implement exponential backoff in spinlocks runniong on ARM, as suggested by: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/multi-threaded-applications-arm

We have noticed throughput almost doubles, on the 32 and 64 thread-count cases within the small locks benchmark.

In the below results, 'Sum' is throughput:

before:

------- folly::MicroSpinLock 32 threads
Sum: 67853388 Mean: 942408 stddev: 108821
Lock time stats in us: mean 3 stddev 63 max 17020
------- folly::MicroSpinLock 64 threads
Sum: 28845120 Mean: 400626 stddev: 61624
Lock time stats in us: mean 9 stddev 149 max 30879

after:

------- folly::MicroSpinLock 32 threads
Sum: 116020339 Mean: 1611393 stddev: 27242
Lock time stats in us: mean 1 stddev 3 max 8394
------- folly::MicroSpinLock 64 threads
Sum: 54264302 Mean: 753670 stddev: 30988
Lock time stats in us: mean 4 stddev 3 max 12924

Reviewed By: Gownta

Differential Revision: D70250664

fbshipit-source-id: 7277fee05b451dafb5e8d61240efd138636b4684
  • Loading branch information
Nicoshev authored and facebook-github-bot committed Feb 27, 2025
1 parent b22f4c5 commit 48940bb
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion folly/synchronization/detail/Sleeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ class Sleeper {
const std::chrono::nanoseconds delta;
uint32_t spinCount;

static constexpr uint32_t kMaxActiveSpin = 4000;
#if FOLLY_AARCH64 && !FOLLY_MOBILE
uint32_t spinCountLog = 1;
#endif

static constexpr uint32_t kMaxActiveSpin = 4096;

public:
static constexpr std::chrono::nanoseconds kMinYieldingSleep =
Expand All @@ -49,8 +53,15 @@ class Sleeper {

void wait() noexcept {
if (spinCount < kMaxActiveSpin) {
#if FOLLY_AARCH64 && !FOLLY_MOBILE
do {
asm_volatile_pause();
} while (++spinCount < spinCountLog);
spinCountLog <<= 1;
#else
++spinCount;
asm_volatile_pause();
#endif
} else {
/* sleep override */
std::this_thread::sleep_for(delta);
Expand Down

0 comments on commit 48940bb

Please sign in to comment.