Commit 6f9321c4 authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

Improve cpu id caching in DigestBuilder

Summary:
`DigestBuilder` caches the cpu id and invalidates it when it detects contention, but the critical section is small enough that it is possible for two thread to end up on a conflicting slot but not detect it for some time, causing cache-line pingponging in the meantime.

Switch to `cachedCurrent()` instead, which uses the number of accesses to invalidate the cache, and is successfully adopted by other high-concurrency primitives.

Reviewed By: yfeldblum

Differential Revision: D27726518

fbshipit-source-id: 05d70ad9f101df4a8797e44cc3cbe94cbd1cb7b8
parent d5bf7f5a
......@@ -23,8 +23,6 @@
namespace folly {
namespace detail {
static thread_local uint32_t tls_lastCpuBufferSlot = 0;
template <typename DigestT>
DigestBuilder<DigestT>::DigestBuilder(size_t bufferSize, size_t digestSize)
: bufferSize_(bufferSize), digestSize_(digestSize) {
......@@ -71,14 +69,9 @@ DigestT DigestBuilder<DigestT>::build() {
template <typename DigestT>
void DigestBuilder<DigestT>::append(double value) {
auto& which = tls_lastCpuBufferSlot;
auto cpuLocalBuf = &cpuLocalBuffers_[which];
std::unique_lock<SpinLock> g(cpuLocalBuf->mutex, std::try_to_lock_t());
if (!g.owns_lock()) {
which = AccessSpreader<>::current(cpuLocalBuffers_.size());
cpuLocalBuf = &cpuLocalBuffers_[which];
g = std::unique_lock<SpinLock>(cpuLocalBuf->mutex);
}
auto cpuLocalBuf = &cpuLocalBuffers_[AccessSpreader<>::cachedCurrent(
cpuLocalBuffers_.size())];
std::unique_lock<SpinLock> g(cpuLocalBuf->mutex);
cpuLocalBuf->buffer.push_back(value);
if (cpuLocalBuf->buffer.size() == bufferSize_) {
if (!cpuLocalBuf->digest) {
......
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