在实现无锁数据结构和定时代码时,通常需要抑制编译器的优化。通常人们使用asm volatile
with memory
在 clobber 列表中,但有时你会看到asm volatile
或者只是一个简单的asm
破坏记忆。
这些不同的语句对代码生成有什么影响(特别是在 GCC 中,因为它不太可能是可移植的)?
仅供参考,这些是有趣的变化:
asm (""); // presumably this has no effect on code generation
asm volatile ("");
asm ("" ::: "memory");
asm volatile ("" ::: "memory");
See the GCC 文档中的“扩展 Asm”页面 http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Extended-Asm.html.
您可以防止asm
写关键字删除指令volatile
之后asm
。 [...] 这volatile
关键字表明该指令具有重要的副作用。 GCC 不会删除volatile
asm 如果可以访问的话。
and
An asm
没有任何输出操作数的指令将被视为与易失性指令相同asm
操作说明。
您的示例都没有指定输出操作数,因此asm
and asm volatile
表单的行为相同:它们在代码中创建一个不能删除的点(除非证明它无法访问)。
这与什么都不做不太一样。看这个问题 https://stackoverflow.com/questions/13955162举个假人的例子asm
这改变了代码生成——在该示例中,循环 1000 次的代码被矢量化为一次计算 16 次循环迭代的代码;但存在一个asm
循环内部抑制了优化(asm
必须达到1000次)。
The "memory"
clobber 使 GCC 假设任何内存都可以被任意读取或写入asm
块,因此将阻止编译器重新排序加载或存储:
这将导致 GCC 不会在汇编指令中将内存值缓存在寄存器中,并且不会优化对该内存的存储或加载。
(但这并不能阻止一个 CPU 相对于另一个 CPU 重新排序加载和存储;为此您需要真正的内存屏障指令。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)