I have tried to replace QMutex
in my application (monte carlo simulation) by std::mutex
, and surprisingly, the computation speed was divided by 3. The mutex locking/unlocking performance cost rised from negligible to about 66% of the threads time.
I digged into implementations sources. I initially thought that both were wrappers to Win32 threads (with an extra layer of pthread for std::thread
), but in fact Qt is not using any kernel functions for the mutexes, and has its own internal implementation based on atomic variables. This one seems much faster.
Thanks
Qt is not using any kernel functions for the mutexes, and has its own internal implementation based on atomic variables
Of course Qt calls the OS to make the thread wait if the mutex is already locked.
The idea here is that in good multithreaded code the chance of waiting on a already locked mutex are extremely low; the common case to optimize is the uncontended mutex, which must be kept as fast as possible.
Hence, QMutex is designed around the Linux futex
system call, and to use atomics and lockfree programming. In the uncontended case, no system calls are necessary, only some clever atomics programming; in the contended case, system calls are necessary (to wait/wake threads), and indeed that's what Qt uses:
For more info behind QMutex design, see here.
Why does the STL not use a similar approach? I have no idea. Possibly because there's native_handle
function which should return "something" in all cases, even when the mutex is unlocked or locked but uncontended, so it always uses the system calls.
(Anyhow, I'm not surprised that Qt outperforms std::mutex
. If it didn't, QMutex would be a wrapper around std::mutex
.)
It sounds like QMutex is implemented with a spinlock. To answer your questions:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With