ASM,ASM挥发,重挫内存之间的区别 [英] The difference between asm, asm volatile and clobbering memory
问题描述
在实现无锁的数据结构和时序code,常常需要用晚餐preSS编译器的优化技术。通常人们做到这一点使用 ASM挥发性
与内存
在撞名单,但有时你看到的只是 ASM挥发性
或只是一个普通的 ASM
重挫内存。
?这些不同的语句对code产生什么样的影响(尤其是在海湾合作委员会,因为它是不太可能便携式)?
仅供参考,这些都是有趣的变化:
ASM(); // presumably这对code一代没有影响
ASM挥发性();
ASM(:::内存);
ASM挥发性(:::内存);
查看的扩展ASM页中的GCC文档。
您可以通过写关键字
挥发性
在<$被删除prevent一个ASM
指令C $ C> ASM 。 [...]的挥发性
关键字表示指令有重要的副作用。 GCC不会删除挥发性
ASM是否可达。
块引用>和
没有任何输出操作数这是
ASM
指令将被同等对待,以挥发性ASM
指令。
块引用>他们创造:你的例子都没有输出操作数指定,因此ASM
和ASM挥发性
形式的行为相同在code点可能不被删除(除非它被证明是无法访问)。
这是不太一样无所事事。请参见这个问题以虚设
ASM
这改变$ C $的例子ç代 - 在这个例子中,code,它绕着一个循环1000次被矢量化到code,它计算循环一次的16次迭代;但在循环中的ASM
的presence抑制优化(在ASM
必须达到1000次)的
记忆
撞使得GCC假设任何内存可以任意读或写的ASM
块,所以将prevent从两端重新排序加载或存储编译器:
这将导致GCC不跨汇编指令寄存器缓存内存的值,而不是优化存储或加载到内存。
块引用>(这并不$ P $从重新排序的载入和存储相对于另一个CPU,虽然pvent一个CPU;你需要真正的内存屏障指令)
When implementing lock-free data structures and timing code it's often necessary to suppress the compiler's optimisations. Normally people do this using
asm volatile
withmemory
in the clobber list, but you sometimes see justasm volatile
or just a plainasm
clobbering memory.What impact do these different statements have on code generation (particularly in GCC, as it's unlikely to be portable)?
Just for reference, these are the interesting variations:
asm (""); // presumably this has no effect on code generation asm volatile (""); asm ("" ::: "memory"); asm volatile ("" ::: "memory");
解决方案See the "Extended Asm" page in the GCC documentation.
You can prevent an
asm
instruction from being deleted by writing the keywordvolatile
after theasm
. [...] Thevolatile
keyword indicates that the instruction has important side-effects. GCC will not delete avolatile
asm if it is reachable.and
An
asm
instruction without any output operands will be treated identically to a volatileasm
instruction.None of your examples have output operands specified, so the
asm
andasm volatile
forms behave identically: they create a point in the code which may not be deleted (unless it is proved to be unreachable).This is not quite the same as doing nothing. See this question for an example of a dummy
asm
which changes code generation - in that example, code that goes round a loop 1000 times gets vectorised into code which calculates 16 iterations of the loop at once; but the presence of anasm
inside the loop inhibits the optimisation (theasm
must be reached 1000 times).The
"memory"
clobber makes GCC assume that any memory may be arbitrarily read or written by theasm
block, so will prevent the compiler from reordering loads or stores across it:This will cause GCC to not keep memory values cached in registers across the assembler instruction and not optimize stores or loads to that memory.
(That does not prevent a CPU from reordering loads and stores with respect to another CPU, though; you need real memory barrier instructions for that.)
这篇关于ASM,ASM挥发,重挫内存之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!