C++11 Synchronization Benchmark

In the previous parts of this serie, we saw some C++11 Synchronization techniques: locks, lock guards and atomic references.

In this small post, I will present the results of a little benchmark I did run to compare the different techniques. In this benchmark, the critical section is a single increment to an integer. The critical section is protected using three techniques:

  • A single std::mutex with calls to lock() and unlock()
  • A single std::mutex locked with std::lock_guard
  • An atomic reference on the integer

The tests have been made with 1, 2, 4, 8, 16, 32, 64 and 128 threads. Each test is repeated 5 times.

The results are presented in the following figure:

C++11 Synchronization Benchmark Result

As expected, the mutex versions are much slower than the atomic one. An interesting point is that the the atomic version has not a very good scalability. I would have expected that the impact of adding one thread would not be that high.

I'm also surprised that the lock guard version has a non-negligible overhead when there are few threads.

In conclusion, do not locks when all you need is modifying integral types. For that, std::atomic is much faster. Good Lock-Free algorithms are almost always faster than the algorithms with lock.

The sources of the benchmark are available on Github: https://github.com/wichtounet/articles/tree/master/src/threads/benchmark

Related articles

  • C++11 Concurrency Tutorial - Part 4: Atomic Types
  • C++11 Concurrency Tutorial - Part 2 : Protect shared data
  • C++11 Concurrency Tutorial - Part 3: Advanced locking and condition variables
  • Java Concurrency – Part 3 : Synchronization with intrinsic locks
  • My Java Benchmarks on GitHub
  • Java Synchronization (Mutual Exclusion) Benchmark
  • Comments

    Comments powered by Disqus