Suppose I have a class foo:
class foo {
static uint32 count_;
pthread_mutex_t mu;
void increase() {
pthread_mutex_lock(&mu);
count_++;
pthread_mutex_unlock(&mu);
}
}
Is there any difference if I don't use mutex, but just have a std::atomic as count_?
Thanks!
There is a huge difference. pthread_mutex_lock
can be very expensive, because it may incorporate a syscall*. An atomic increment yields lock xadd
.
Another advantage is that std::atomic<...>
is maybe better portable, because it is part of the C++ standard. Pthread calls will most likely not work in Windows.
*) To let the current thread sleep if the lock is already held by some other thread. But most likely only a spinlock will occur.
It is highly likely that the mutex lock is in fact implemented as an atomic increment in itself, and if you have the bad luck of getting contention on the lock, also involving a system call [assuming of course, that it isn't a system call either way!].
The atomic solution, on x86 will be a simple "lock add" operation. On other processors it may be more complex, but even so, the atomic is the minimum required for a mutex, so you have AT least that amount of work anyway.
Then you add the mutex unlock, which may not be quite as complex, but it will not be completely free.
So, yes, go for atomic.
But like all things to do with performance, do measure a "before" and "after", to see that it actually does improve performance.
Note that I have seen someone explain that the original gnu C++ standard library implementation was actually done using some sort of mutex around the operation, but I believe if you have a reasonably recent version of g++ it should be fine (at least for x86 type processors). Microsoft has for a long time supported proper atomic operations as builtins, so should be fine there. Other processor architectures may vary.
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