我一直在阅读有关编译器优化与 CPU 优化的文章,以及 volatile
vs 内存障碍。
我不清楚的一件事是,我目前的理解是 CPU 优化和编译器优化是正交的。 IE。可以相互独立发生。
然而,文章volatile considered harmful说明 volatile
不应该使用。莱纳斯的 post提出类似的主张。 IIUC 的主要原因是将变量标记为 volatile
在访问该变量时禁用所有编译器优化(即,即使它们无害),同时仍不提供针对内存重新排序的保护。从本质上讲,重点是不应该小心处理数据,而是需要小心处理特定的访问模式。
现在,volatile considered harmful文章给出了以下等待标志的忙循环示例:
while (my_variable != what_i_want) {}
并指出编译器可以优化对
my_variable
的访问以便它只发生一次而不是循环。文章声称的解决方案如下:while (my_variable != what_i_want)
cpu_relax();
据说
cpu_relax
充当 编译器屏障 (文章的早期版本说它是 内存屏障 )。我在这里有几个差距:
1) 是否暗示 gcc 对
cpu_relax
有特殊的了解调用,并将其转换为对编译器和 CPU 的提示?2) 其他指令如
smb_mb()
也是如此和喜欢?3) 鉴于
cpu_relax
,这是如何工作的本质上定义为 C 宏?如果我手动展开 cpu_relax
gcc 还会将它视为编译器障碍吗?我如何知道 gcc 尊重哪些调用?4)
cpu_relax
的范围是什么?就gcc而言?换句话说,gcc 看到 cpu_relax
时无法优化的读取范围是多少?操作说明?从 CPU 的角度来看,范围很广(内存屏障在读或写缓冲区中放置一个标记)。我猜 gcc 使用较小的范围 - 也许是 C 范围?
最佳答案
cpu_relax
的语义有特殊的了解。或者它扩展到的任何东西,并且必须将其转换为硬件也尊重语义的东西。 关于gcc 和 cpu_relax、smb_mb 等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47975191/