Joh*_*n S 5 c++ multithreading atomic c++11 stdatomic
考虑以下代码:
// global
std::atomic<bool> run = true;
// thread 1
while (run) { /* do stuff */ }
// thread 2
/* do stuff until it's time to shut down */
run = false;
Run Code Online (Sandbox Code Playgroud)
我是否需要与原子变量相关的开销?我的直觉是,布尔变量的读/写无论如何都或多或少是原子的(这是常见的g ++/Linux/Intel设置)并且如果有一些写/读时序的怪异,并且我在线程1上的运行循环停止一个结果提前或结束,我对这个应用程序并不十分担心.
或者我在这里缺少一些其他考虑因素?看看perf,看来我的代码花费了相当多的时间,std::atomic_bool::operator bool而我宁愿把它放在循环中.
Sha*_*ger 11
您需要使用std::atomic以避免不希望的优化(编译器一次读取值并始终循环或从不循环)并在没有强排序内存模型的系统上获得正确的行为(x86是强有序的,因此一旦写完成,下一次读取会看到它;在其他系统上,如果线程由于其他原因没有将CPU缓存刷新到主RAM,那么写入可能很长时间都没有看到,如果有的话).
您可以改善性能.默认使用std::atomic使用序列一致性模型,该模型对于单个标志值来说是过度的.您可以通过使用load/ store使用显式(并且不太严格)的内存排序来加速它,因此每个load都不需要使用最偏执模式来保持一致性.
例如,您可以这样做:
// global
std::atomic<bool> run = true;
// thread 1
while (run.load(std::memory_order_acquire)) { /* do stuff */ }
// thread 2
/* do stuff until it's time to shut down */
run.store(false, std::memory_order_release);
Run Code Online (Sandbox Code Playgroud)
在x86机器上,任何比(默认的,最严格的)顺序一致性排序更严格的排序通常最终什么都不做,只是确保指令按特定顺序执行; 由于强有序的存储器模型,不需要总线锁定等.因此,除了保证值实际上是从内存中读取,而不是缓存到寄存器并重用,在x86上使用原子这种方式是免费的,而在非x86机器上,它使你的代码正确(否则它不会是).