cmpl
指令是否等同于movl
+比较。如果是这样,有什么区别b / w:(1)
LBB1_2:
cmpl $0, _data_ready(%rip)
je LBB1_2
和: (2)
LBB1_2:
movl _data_ready(%rip), %eax
testl %eax, %eax
je LBB1_2
为while (!data_ready);
生成(1),其中data_ready为volatile int data_ready = 0x0;
while (!data_ready.load(std::memory_order_acquire));
生成(2),其中data_ready为std::atomic<int> data_ready(0x0);
在这两种情况下,data_ready由另一个线程设置为1。
英特尔保证movl
对于对齐的内存访问是原子的,似乎cmpl
也应该是原子的。如果是这样的话,为什么clang生成不同的代码? (我确信有正当理由,这就是我要问的原因)
另外,这是否意味着一个volatile变量与x86-64平台上的std :: atomic“等效”(这当然没有任何意义,并且不受C ++标准的保证)。
生成此代码的代码可用in this github repo
答案 0 :(得分:0)
test
指令执行其AND
指令,并根据AND
的结果设置标志(但and
本身的结果是丢弃)。
cmp
在执行操作时类似于设置标志,但它执行减法而不是按位AND
。
虽然该操作与volatile
或atomic
的关系并不多(如果有的话)。在任何一个影响代码生成的情况下,效果将是所使用的寻址模式 - 即,第一个直接将立即值与内存中的值进行比较,但第二个执行加载,然后操纵值在登记册中。