Mutex lock speed difference inside and outisde the foor loop

2.1k views Asked by At

I am confused of speed different between using the mutex lock() and unlock() inside and outside a for loop. I got a global variable value and a function that increments it 1000000 times. This function is run in parallel by 5 threads. I measured the time elapsed and got these results:

    mutex.lock();
    for(int i = 0; i < 1000000; i++)
    {
        value++;
    }
    mutex.unlock();

0.160921 seconds

and:

    for(int i = 0; i < 1000000; i++)
    {        
        mutex.lock();
        value++;
        mutex.unlock();
    }

2.10521 seconds

I assume with the second inner mutex arrangement the control is too fine and a lot of time is spent between the threads switching? or is there something else?

1

There are 1 answers

0
Sebastian Redl On

Locking and unlocking a mutex takes some time. Specifically, it takes a LOT more time than incrementing an integer. Your second example is just testing the lock/unlock speed, and also adds the task switching overhead, because at any point where the mutex is unlocked, a different thread could take over.

And in the first, the compiler could just replace the loop by a single addition. And because the entirety of the thread's function is covered by the mutex, there's no parallel execution; all threads but one are just blocked until the loop of the one is complete, meaning that the code is equivalent to just having the loop five times in a row on a single thread.

This has little to do with fine- vs coarse-grained locking. Those strategies are about whether you have few locks covering lots of resources, or many locks covering few resources. You have just one resource (the global int) and thus no decision to make.

Instead this is about whether to lock the mutex just for a short time, thus leaving it open the rest of the time for other threads to do work, or lock it for longer periods to avoid overhead, but reducing parallelism. However, since your threads don't do anything except accessing the protected resource, there is no "rest of the time". Your problem (incrementing an integer 5000000 times) has no inherent parallelism in the first place, and thus nothing for multiple threads to exploit.