proxygen
SmallLocksBenchmark.cpp File Reference
#include <algorithm>
#include <cmath>
#include <condition_variable>
#include <numeric>
#include <thread>
#include <vector>
#include <google/base/spinlock.h>
#include <folly/Benchmark.h>
#include <folly/SharedMutex.h>
#include <folly/synchronization/DistributedMutex.h>
#include <folly/synchronization/SmallLocks.h>

Go to the source code of this file.

Classes

class  InitLock< Lock >
 
class  GoogleSpinLockAdapter
 
struct  VirtualBase
 
struct  VirtualImpl
 

Macros

#define BENCH_BASE(...)   FB_VA_GLUE(BENCHMARK_NAMED_PARAM, (__VA_ARGS__))
 
#define BENCH_REL(...)   FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM, (__VA_ARGS__))
 
#define FairnessTest(type)
 

Functions

 DEFINE_int32 (work, 100,"Number of work cycles")
 
 DEFINE_int32 (unlocked_work, 1000,"Number of unlocked work cycles")
 
 DEFINE_int32 (threads, std::thread::hardware_concurrency(),"Number of threads for fairness test")
 
static void burn (size_t n)
 
template<typename Lock >
static void runContended (size_t numOps, size_t numThreads)
 
template<typename Lock >
static void runFairness ()
 
template<typename Mutex >
void runUncontended (std::size_t iters)
 
 BENCHMARK (StdMutexUncontendedBenchmark, iters)
 
 BENCHMARK (GoogleSpinUncontendedBenchmark, iters)
 
 BENCHMARK (MicroSpinLockUncontendedBenchmark, iters)
 
 BENCHMARK (PicoSpinLockUncontendedBenchmark, iters)
 
 BENCHMARK (MicroLockUncontendedBenchmark, iters)
 
 BENCHMARK (SharedMutexUncontendedBenchmark, iters)
 
 BENCHMARK (DistributedMutexUncontendedBenchmark, iters)
 
 BENCHMARK (AtomicFetchAddUncontendedBenchmark, iters)
 
 __attribute__ ((noinline, noclone)) VirtualBase *makeVirtual()
 
 BENCHMARK (VirtualFunctionCall, iters)
 
 BENCHMARK_DRAW_LINE ()
 
static void std_mutex (size_t numOps, size_t numThreads)
 
static void google_spin (size_t numOps, size_t numThreads)
 
static void folly_microspin (size_t numOps, size_t numThreads)
 
static void folly_picospin (size_t numOps, size_t numThreads)
 
static void folly_microlock (size_t numOps, size_t numThreads)
 
static void folly_sharedmutex (size_t numOps, size_t numThreads)
 
static void folly_distributedmutex (size_t numOps, size_t numThreads)
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 1thread, 1)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 1thread, 1)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 1thread, 1)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 1thread, 1)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 2thread, 2)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 2thread, 2)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 2thread, 2)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 2thread, 2)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 4thread, 4)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 4thread, 4)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 4thread, 4)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 4thread, 4)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 8thread, 8)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 8thread, 8)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 8thread, 8)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 8thread, 8)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 16thread, 16)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 16thread, 16)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 16thread, 16)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 16thread, 16)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 32thread, 32)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 32thread, 32)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 32thread, 32)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 32thread, 32)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 64thread, 64)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 64thread, 64)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 64thread, 64)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 64thread, 64)) BENCHMARK_DRAW_LINE()
 
 FB_VA_GLUE (BENCHMARK_NAMED_PARAM,(std_mutex, 128thread, 128)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microspin, 128thread, 128)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_microlock, 128thread, 128)) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM
 
 FB_VA_GLUE (BENCHMARK_RELATIVE_NAMED_PARAM,(folly_distributedmutex, 128thread, 128)) int main(int argc
 
 runFairness< std::mutex > ()
 
 runFairness< GoogleSpinLockAdapter > ()
 
 runFairness< InitLock< folly::MicroSpinLock > > ()
 
 runFairness< InitLock< folly::PicoSpinLock< uint16_t > > > ()
 
 runFairness< InitLock< folly::MicroLock > > ()
 
 runFairness< folly::SharedMutex > ()
 
 runFairness< folly::DistributedMutex > ()
 

Variables

 google_spin
 
 folly_picospin
 
 folly_sharedmutex
 
char ** argv
 
 return
 

Macro Definition Documentation

#define BENCH_BASE (   ...)    FB_VA_GLUE(BENCHMARK_NAMED_PARAM, (__VA_ARGS__))

Definition at line 334 of file SmallLocksBenchmark.cpp.

Referenced by folly_distributedmutex().

#define BENCH_REL (   ...)    FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM, (__VA_ARGS__))

Definition at line 335 of file SmallLocksBenchmark.cpp.

#define FairnessTest (   type)
Value:
{ \
printf(#type ": \n"); \
runFairness<type>(); \
}
PskType type

Function Documentation

__attribute__ ( (noinline, noclone)  )

Definition at line 319 of file SmallLocksBenchmark.cpp.

Referenced by folly::SingletonVault::scheduleDestroyInstances().

319  {
320  return new VirtualImpl();
321 }
BENCHMARK ( StdMutexUncontendedBenchmark  ,
iters   
)

Definition at line 272 of file SmallLocksBenchmark.cpp.

272  {
273  runUncontended<std::mutex>(iters);
274 }
BENCHMARK ( GoogleSpinUncontendedBenchmark  ,
iters   
)

Definition at line 276 of file SmallLocksBenchmark.cpp.

276  {
277  runUncontended<GoogleSpinLockAdapter>(iters);
278 }
BENCHMARK ( MicroSpinLockUncontendedBenchmark  ,
iters   
)

Definition at line 280 of file SmallLocksBenchmark.cpp.

280  {
281  runUncontended<InitLock<folly::MicroSpinLock>>(iters);
282 }
BENCHMARK ( PicoSpinLockUncontendedBenchmark  ,
iters   
)

Definition at line 284 of file SmallLocksBenchmark.cpp.

284  {
285  runUncontended<InitLock<folly::PicoSpinLock<std::uint16_t>>>(iters);
286 }
BENCHMARK ( MicroLockUncontendedBenchmark  ,
iters   
)

Definition at line 288 of file SmallLocksBenchmark.cpp.

288  {
289  runUncontended<InitLock<folly::MicroLock>>(iters);
290 }
BENCHMARK ( SharedMutexUncontendedBenchmark  ,
iters   
)

Definition at line 292 of file SmallLocksBenchmark.cpp.

292  {
293  runUncontended<folly::SharedMutex>(iters);
294 }
BENCHMARK ( DistributedMutexUncontendedBenchmark  ,
iters   
)

Definition at line 296 of file SmallLocksBenchmark.cpp.

296  {
297  runUncontended<folly::DistributedMutex>(iters);
298 }
BENCHMARK ( AtomicFetchAddUncontendedBenchmark  ,
iters   
)

Definition at line 300 of file SmallLocksBenchmark.cpp.

References folly::doNotOptimizeAway().

300  {
301  auto&& atomic = std::atomic<uint64_t>{0};
302  while (iters--) {
303  folly::doNotOptimizeAway(atomic.fetch_add(1));
304  }
305 }
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
BENCHMARK ( VirtualFunctionCall  ,
iters   
)

Definition at line 323 of file SmallLocksBenchmark.cpp.

References BENCHMARK_DRAW_LINE(), and VirtualBase::foo().

323  {
324  VirtualBase* vb = makeVirtual();
325  while (iters--) {
326  vb->foo();
327  }
328  delete vb;
329 }
virtual void foo()=0
BENCHMARK_DRAW_LINE ( )
static void burn ( size_t  n)
static

Definition at line 44 of file SmallLocksBenchmark.cpp.

References count, folly::doNotOptimizeAway(), i, folly::detail::distributed_mutex::DistributedMutex< Atomic, TimePublishing >::lock(), folly::detail::lock(), folly::gen::move, mutex, Mutex, folly::detail::distributed_mutex::DistributedMutex< Atomic, TimePublishing >::unlock(), and folly::detail::distributed_mutex::wait().

Referenced by runContended(), and runFairness().

44  {
45  for (size_t i = 0; i < n; ++i) {
47  }
48 }
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
DEFINE_int32 ( work  ,
100  ,
"Number of work cycles"   
)
DEFINE_int32 ( unlocked_work  ,
1000  ,
"Number of unlocked work cycles"   
)
DEFINE_int32 ( threads  ,
std::thread::hardware_concurrency()  ,
"Number of threads for fairness test  
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 1thread, 1)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 1thread, 1)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 1thread, 1)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 1thread, 1)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 2thread, 2)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 2thread, 2)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 2thread, 2)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 2thread, 2)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 4thread, 4)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 4thread, 4)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 4thread, 4)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 4thread, 4)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 8thread, 8)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 8thread, 8)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 8thread, 8)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 8thread, 8)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 16thread, 16)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 16thread, 16)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 16thread, 16)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 16thread, 16)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 32thread, 32)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 32thread, 32)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 32thread, 32)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 32thread, 32)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 64thread, 64)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 64thread, 64)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 64thread, 64)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 64thread, 64)   
)
FB_VA_GLUE ( BENCHMARK_NAMED_PARAM  ,
(std_mutex, 128thread, 128)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microspin, 128thread, 128)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_microlock, 128thread, 128)   
)
FB_VA_GLUE ( BENCHMARK_RELATIVE_NAMED_PARAM  ,
(folly_distributedmutex, 128thread, 128)   
)
static void folly_distributedmutex ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 355 of file SmallLocksBenchmark.cpp.

References BENCH_BASE, BENCHMARK_DRAW_LINE(), and std_mutex().

355  {
356  runContended<folly::DistributedMutex>(numOps, numThreads);
357 }
static void folly_microlock ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 349 of file SmallLocksBenchmark.cpp.

349  {
350  runContended<folly::MicroLock>(numOps, numThreads);
351 }
static void folly_microspin ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 343 of file SmallLocksBenchmark.cpp.

343  {
344  runContended<InitLock<folly::MicroSpinLock>>(numOps, numThreads);
345 }
static void folly_picospin ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 346 of file SmallLocksBenchmark.cpp.

346  {
347  runContended<InitLock<folly::PicoSpinLock<uint16_t>>>(numOps, numThreads);
348 }
static void folly_sharedmutex ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 352 of file SmallLocksBenchmark.cpp.

352  {
353  runContended<folly::SharedMutex>(numOps, numThreads);
354 }
static void google_spin ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 340 of file SmallLocksBenchmark.cpp.

340  {
341  runContended<GoogleSpinLockAdapter>(numOps, numThreads);
342 }
template<typename Lock >
static void runContended ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 115 of file SmallLocksBenchmark.cpp.

References burn(), folly::BenchmarkSuspender::dismissing(), folly::detail::lock(), folly::ssl::detail::locks(), folly::gen::move, mutex, folly::pushmi::detail::t, threads, and value.

115  {
117  size_t totalthreads = std::thread::hardware_concurrency();
118  if (totalthreads < numThreads) {
119  totalthreads = numThreads;
120  }
121  size_t threadgroups = totalthreads / numThreads;
122  struct lockstruct {
123  char padding1[128];
124  Lock mutex;
125  char padding2[128];
126  long value = 1;
127  };
128 
129  auto locks =
130  (struct lockstruct*)calloc(threadgroups, sizeof(struct lockstruct));
131 
132  char padding3[128];
133  (void)padding3;
134  std::vector<std::thread> threads(totalthreads);
135 
136  SimpleBarrier runbarrier(totalthreads + 1);
137 
138  for (size_t t = 0; t < totalthreads; ++t) {
139  threads[t] = std::thread([&, t] {
140  lockstruct* mutex = &locks[t % threadgroups];
141  runbarrier.wait();
142  for (size_t op = 0; op < numOps; op += 1) {
143  auto state = lock(mutex->mutex);
144  burn(FLAGS_work);
145  mutex->value++;
146  unlock(mutex->mutex, std::move(state));
147  burn(FLAGS_unlocked_work);
148  }
149  });
150  }
151 
152  runbarrier.wait();
153  braces.dismissing([&] {
154  for (auto& thr : threads) {
155  thr.join();
156  }
157  });
158 }
static std::unique_ptr< SSLLock[]> & locks()
static void burn(size_t n)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::vector< std::thread::id > threads
auto lock(SynchronizedLocker...lockersIn) -> std::tuple< typename SynchronizedLocker::LockedPtr... >
Definition: Synchronized.h:871
static const char *const value
Definition: Conv.cpp:50
std::mutex mutex
auto dismissing(F f) -> invoke_result_t< F >
Definition: Benchmark.h:130
state
Definition: http_parser.c:272
template<typename Lock >
static void runFairness ( )
static

Definition at line 161 of file SmallLocksBenchmark.cpp.

References folly::f14::accumulate(), burn(), diff(), for_each(), g(), folly::detail::lock(), folly::ssl::detail::locks(), m, max, folly::gen::move, mutex, now(), folly::detail::rlock(), stop(), sum(), folly::pushmi::detail::t, threads, folly::detail::distributed_mutex::time(), and value.

161  {
162  size_t numThreads = FLAGS_threads;
163  size_t totalthreads = std::thread::hardware_concurrency();
164  if (totalthreads < numThreads) {
165  totalthreads = numThreads;
166  }
167  long threadgroups = totalthreads / numThreads;
168  struct lockstruct {
169  char padding1[128];
170  Lock lock;
171  };
172 
173  auto locks =
174  (struct lockstruct*)calloc(threadgroups, sizeof(struct lockstruct));
175 
176  char padding3[64];
177  (void)padding3;
178  std::vector<std::thread> threads(totalthreads);
179 
180  std::atomic<bool> stop{false};
181 
183  std::vector<long> results;
184  std::vector<std::chrono::microseconds> maxes;
185 
186  std::vector<std::chrono::microseconds> aqTime;
187  std::vector<unsigned long> aqTimeSq;
188 
189  SimpleBarrier runbarrier(totalthreads + 1);
190 
191  for (size_t t = 0; t < totalthreads; ++t) {
192  threads[t] = std::thread([&, t] {
193  lockstruct* mutex = &locks[t % threadgroups];
194  long value = 0;
195  std::chrono::microseconds max(0);
196  std::chrono::microseconds time(0);
197  unsigned long timeSq(0);
198  runbarrier.wait();
199  while (!stop) {
200  std::chrono::steady_clock::time_point prelock =
202  auto state = lock(mutex->lock);
203  std::chrono::steady_clock::time_point postlock =
205  auto diff = std::chrono::duration_cast<std::chrono::microseconds>(
206  postlock - prelock);
207  time += diff;
208  timeSq += diff.count() * diff.count();
209  if (diff > max) {
210  max = diff;
211  }
212  burn(FLAGS_work);
213  value++;
214  unlock(mutex->lock, std::move(state));
215  burn(FLAGS_unlocked_work);
216  }
217  {
218  std::lock_guard<std::mutex> g(rlock);
219  results.push_back(value);
220  maxes.push_back(max);
221  aqTime.push_back(time);
222  aqTimeSq.push_back(timeSq);
223  }
224  });
225  }
226 
227  runbarrier.wait();
228  /* sleep override */
229  std::this_thread::sleep_for(std::chrono::seconds(2));
230  stop = true;
231 
232  for (auto& thr : threads) {
233  thr.join();
234  }
235 
236  // Calulate some stats
237  unsigned long sum = std::accumulate(results.begin(), results.end(), 0.0);
238  double m = sum / results.size();
239 
240  double accum = 0.0;
241  std::for_each(results.begin(), results.end(), [&](const double d) {
242  accum += (d - m) * (d - m);
243  });
244  double stdev = std::sqrt(accum / (results.size() - 1));
245  std::chrono::microseconds mx = *std::max_element(maxes.begin(), maxes.end());
246  std::chrono::microseconds agAqTime = std::accumulate(
247  aqTime.begin(), aqTime.end(), std::chrono::microseconds(0));
248  unsigned long agAqTimeSq =
249  std::accumulate(aqTimeSq.begin(), aqTimeSq.end(), 0);
250  std::chrono::microseconds mean = agAqTime / sum;
251  double variance = (sum * agAqTimeSq - (agAqTime.count() * agAqTime.count())) /
252  sum / (sum - 1);
253  double stddev2 = std::sqrt(variance);
254 
255  printf("Sum: %li Mean: %.0f stddev: %.0f\n", sum, m, stdev);
256  printf(
257  "Lock time stats in us: mean %li stddev %.0f max %li\n",
258  mean.count(),
259  stddev2,
260  mx.count());
261 }
std::atomic< int64_t > sum(0)
void accumulate(std::vector< std::size_t > &a, std::vector< std::size_t > const &d)
Definition: F14TestUtil.h:58
static std::unique_ptr< SSLLock[]> & locks()
LogLevel max
Definition: LogLevel.cpp:31
static void burn(size_t n)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::chrono::steady_clock::time_point now()
auto rlock(Synchronized &synchronized, Args &&...args)
Definition: Synchronized.h:935
std::vector< std::thread::id > threads
static void stop()
auto lock(SynchronizedLocker...lockersIn) -> std::tuple< typename SynchronizedLocker::LockedPtr... >
Definition: Synchronized.h:871
static map< string, int > m
static const char *const value
Definition: Conv.cpp:50
uint64_t diff(uint64_t a, uint64_t b)
Definition: FutexTest.cpp:135
std::mutex mutex
g_t g(f_t)
void for_each(T const &range, Function< void(typename T::value_type const &) const > const &func)
std::chrono::nanoseconds time()
state
Definition: http_parser.c:272
template<typename Mutex >
void runUncontended ( std::size_t  iters)

Definition at line 264 of file SmallLocksBenchmark.cpp.

References i, folly::detail::lock(), folly::gen::move, mutex, and Mutex.

264  {
265  auto&& mutex = Mutex{};
266  for (auto i = std::size_t{0}; i < iters; ++i) {
267  auto state = lock(mutex);
268  unlock(mutex, std::move(state));
269  }
270 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define Mutex
auto lock(SynchronizedLocker...lockersIn) -> std::tuple< typename SynchronizedLocker::LockedPtr... >
Definition: Synchronized.h:871
std::mutex mutex
state
Definition: http_parser.c:272
static void std_mutex ( size_t  numOps,
size_t  numThreads 
)
static

Definition at line 337 of file SmallLocksBenchmark.cpp.

Referenced by folly_distributedmutex().

337  {
338  runContended<std::mutex>(numOps, numThreads);
339 }

Variable Documentation

folly_picospin

Definition at line 363 of file SmallLocksBenchmark.cpp.

folly_sharedmutex

Definition at line 365 of file SmallLocksBenchmark.cpp.

google_spin

Definition at line 361 of file SmallLocksBenchmark.cpp.

return

Definition at line 443 of file SmallLocksBenchmark.cpp.