简体   繁体   中英

x86-64 movl and cmpl difference

Is cmpl instruction equivalent to movl + a compare. If so, what's the difference b/w: (1)

LBB1_2:    
     cmpl $0, _data_ready(%rip)
     je LBB1_2

and: (2)

LBB1_2:
    movl    _data_ready(%rip), %eax
    testl %eax, %eax
    je LBB1_2

(1) is generated for while (!data_ready); where data_ready is volatile int data_ready = 0x0;

(2) is generated for while (!data_ready.load(std::memory_order_acquire)); where data_ready is std::atomic<int> data_ready(0x0);

In both cases data_ready is set to 1 by another thread. Intel guarantees movl to be atomic for aligned memory access and it seems like cmpl should be atomic too. If that's the case why is clang generating different codes? (I am sure there is valid reasons that's why I am asking)

Also, does this mean that a volatile variable is "equivalent" to an std::atomic on x86-64 platforms (which means nothing of course and is not guaranteed by the C++ standard).

The code that generates this is available in this github repo

The test instruction does a bitwise AND of its instructions, and sets the flags based on the result of that AND (but the result of the and itself is discarded).

The cmp is similar in doing an operation only to set the flags, but it does subtraction instead of bitwise AND .

The operation doesn't really have much (if anything) to do with volatile or atomic though. To the extent that either of those affects code generation, the effect would be on the addressing mode used--ie, where the first one compares an immediate value directly to a value in memory, but the second does a load, then manipulates the value in the register.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM