Comparison of std::mutex and std::atomic performance

The following C++ code compares the performance of std::atomic and std::mutex:

#include <atomic>
#include <mutex>
#include <iostream>
#include <chrono>
#include <thread>

const size_t size = 100000000;
std::mutex mutex;
bool var = false;

typedef std::chrono::high_resolution_clock Clock;

void testA()
{
    std::atomic<bool> sync(true);
    const auto start_time = Clock::now();
    for (size_t counter = 0; counter < size; counter++)
    {
        var = sync.load();
        //sync.store(true);
        //sync.exchange(true);
    }
    const auto end_time = Clock::now();
    std::cout << 1e-6*std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << " s\n";
}

void testB()
{
    const auto start_time = Clock::now();
    for (size_t counter = 0; counter < size; counter++)
    {
        std::unique_lock<std::mutex> lock(mutex);
        var=!var;
    }
    const auto end_time = Clock::now();
    std::cout << 1e-6*std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << " s\n";
}

int main()
{
    std::thread t1(testA);
    t1.join();
    std::thread t2(testB);
    t2.join();
}

The code can be compiled with GCC using the following command:

g++ -std=c++11 -pthread -O3 test.cpp -o test

On x86/64 platform (Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz, family 6, model 60, cores 4, Ubuntu 14.04.5 LTS, Trusty Tahr) the output is:

0.044558 s
1.90761 s

so, atomic::load() is 42 times faster then locking and unlocking std::mutex. It is interesting that -O3 option gives significant optimization, without this option the output is:

0.584058 s
3.091 s

std::lock_guard and std::unique_lock, takes the same time, std::mutex and std::recursive_mutex are also very close.

5 Responses to Comparison of std::mutex and std::atomic performance

  1. I’m afraid you’re comparing two routines that don’t do the same thing.
    The line ‘var = sync.load();’ doesn’t change the state of ‘var’, as in the other test.

    1. dmitriano says:

      Theoretically ‘var’ can be removed from the code, but probably I used it to prevent something from being optimized.

  2. Cruz Jean says:

    it’s a bit unfair to use std::unique_lock because it has to go through additional indirection to reach the mutex. std::lock_guard or direct use of std::mutex::lock/unlock would be a better comparison

    1. dmitriano says:

      I am not sure, probably you are right, but read to the end of the post. I used them both and did not notice a significant difference.

Leave a Reply to Luiz Silveira Cancel reply

Your email address will not be published. Required fields are marked *