c++ - 我需要 std::atomic<bool> 还是 POD bool 足够好?

标签 c++ multithreading c++11 atomic 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;

我在这里需要与原子变量相关的开销吗?我的直觉是, bool 变量的读/写或多或少是原子的(这是一个常见的 g++/Linux/Intel 设置),如果有一些写/读时序异常,我在线程 1 上的运行循环会停止一个结果是早晚通过,对于这个应用程序我不是很担心。

还是我在这里遗漏了一些其他考虑因素?查看 perf,我的代码似乎在 std::atomic_bool::operator bool 中花费了相当多的时间,我宁愿将它放在循环中。

最佳答案

您需要使用 std::atomic 来避免不需要的优化(编译器读取一次值并且总是循环或从不循环)并在没有强序内存模型的系统上获得正确的行为( x86 是强序的,所以一旦写入完成,下一次读取就会看到它;在其他系统上,如果线程由于其他原因没有将 CPU 缓存刷新到主 RAM,则写入可能很长时间都看不到,如果曾经)。

不过您可以提高性能。 std::atomic 的默认使用使用 a sequential consistency model这对于单个标志值来说太过分了。您可以通过使用具有显式(且不太严格)内存排序的 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);

在 x86 机器上,任何低于(默认,最严格的)顺序一致性排序的排序通常最终只会确保指令以特定顺序执行;由于强序内存模型,不需要总线锁定等。因此,除了保证值实际上是从内存中读取的,而不是缓存到寄存器中并重复使用之外,在 x86 上以这种方式使用原子是免费的,在非 x86 机器上,它使您的代码正确(否则它不会).

关于c++ - 我需要 std::atomic<bool> 还是 POD bool 足够好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44685403/

相关文章:

c++ - 使用 TBB parallel_for_each() 减少原子计数器

c++ - 在 OpenGL 中将深度渲染到纹理时出现奇怪的结果

c++ - 关闭后等待文件删除

c++ - 模板特化和静态局部变量

c++ - 使用 std::function 和 std::bind 来存储回调和处理对象删除。

c++11 - Boost.Spirit或Antlr是否支持左递归语法

c++ - 将非特化类作为模板参数传入

python - 如何在 Matplotlib 中与线程一起执行动画?

c# - 如何从不同的线程访问变量?

c++ - 使用 QueuedConnection 还是 QMutex 来使对象线程安全?