どちらも排他制御にかかわる仕組みである。 どのような場合に、どちらを選ぶべきか
https://teratail.com/questions/54740
「mutexそれ自体が重い」というのは単なる盲信の事が多いと思います。mutexロック獲得・解放にかかる処理負荷は実処理に比べれば無視できる程度ですし、もしそうでないならば根本的な設計に重篤な問題を抱えています。
並行処理においては、ほとんどすべてのケースでmutexの利用を強く推奨します。atomicを用いて正しい並行処理を実装するのは非常に困難です。並行処理のデバッグで地獄を見たくなければ、処理速度よりもまずは正しいことが自明なプログラムを書くべきです。
複数の変数をアクセスする場合、mutex保護が一番確実で性能も良いですよ。 保護が必要な変数って完成するまでの間に意外に増えますし、完成後も仕様変更で追加する必要が出てくることもそれなりにあります。 更に、無理やり変数を1つにしてもそれがアトミックにアクセスされない型なら結局mutexで保護されますし。
つまり、マルチ・スレッドに於ける変数のアクセス保護は、まずはmutexを使うのが良いと思います。そして、一旦完成し、保護が必要な変数が1つだけで、かつ、アトミックにアクセスされることが期待でき、今後変数の追加が考えにくいケースでのみstd::atmicを使うことが望ましいと思います。
multithreading - Which is more efficient, basic mutex lock or atomic integer? - Stack Overflow
- atomic は成功するまで繰り返す(他のスレッドにスイッチしてくれない)ので、競合発生頻度が高いと、不利である。
Summing up, in general atomic operations are faster if contention between threads is sufficiently low. You should definitely do benchmarking as there's no other reliable method of knowing what's the lowest overhead between context-switching and busy-waiting.
- そもそも mutex のlock/unlock は atomic な操作を必要とするので、最良でも mutex は atomic 操作の2倍コストがかかる
Mutexes eventually end up being implemented with atomics. Since you need at least one atomic operation to lock a mutex, and one atomic operation to unlock a mutex, it takes at least twice long to do a mutex lock, even in the best of cases.
Comparison: Lockless programming with atomics in C++ 11 vs. mutex and RW-locks - ArangoDB
- Windows の mutex は特に遅い。
We can see here that Windows delivers an extraordinary bad performance with std::Mutex; Dave explains why: It seems as if in windows std::mutex is similar to std::recursive_mutex using the Critical_Section system call which has a significant larger overhead and is to be avoided. SRW Locks are sufficient for ArangoDBs use of mutexes, and are therefore preferred. However, on Mac OS X, RW-Locks don’t deliver better performance, neither on Linux/ARM.
結論
atomic は単一の変数に対するmutexに比べて、確かにコストは低いが、難しいし、複数の変数になると結局mutexで保護した方が良いので 基本的に mutex を使う、で良い。