Ash*_*hot 7 c++ multithreading compiler-optimization busy-waiting
#include <iostream>
#include <thread>
#include <mutex>
int main()
{
std::atomic<bool> ready = false;
std::thread threadB = std::thread([&]() {
while (!ready) {}
printf("Hello from B\n");
});
std::this_thread::sleep_for(std::chrono::seconds(1));
printf("Hello from A\n");
ready = true;
threadB.join();
printf("Hello again from A\n");
}
Run Code Online (Sandbox Code Playgroud)
这是 CppCon 演讲中的一个例子https://www.youtube.com/watch?v=F6Ipn7gCOsY&ab_channel=CppCon(17分钟)
目标是先打印Hello from A
然后允许threadB
开始。很明显,应该避免忙等待,因为它使用了大量的 CPU。
作者说while (!ready) {}
循环可以ready
由编译器优化(通过将 的值放入寄存器),因为编译器看到threadB
从不睡觉所以ready
永远不会改变。但是即使线程从不休眠,另一个线程仍然可以更改该值,对吗?没有数据竞争,因为它ready
是原子的。作者声明这个代码是UB。有人可以解释为什么允许编译器进行这样的优化吗?
作者在视频下方的其中一条评论中承认他错了:
我是这么想的,但看来我错了;编译器无法从循环中提升原子读取。@17:54 的建议仍然是正确的——你仍然应该非常小心,并注意编译器可能会重新排序、合并或消除一般原子访问的情况——但这个特定的 while 循环实际上并不是这样的情况。有关编译器如何优化原子访问模式的一些(主要是理论)示例,请参阅 JF Bastien 的 N4455“没有理智的编译器会优化原子” http://www.open-std.org/jtc1/sc22/wg21/docs/papers /2015/n4455.html
归档时间: |
|
查看次数: |
153 次 |
最近记录: |