On Friday, 7 February 2014 at 15:42:06 UTC, Sean Kelly wrote:

Oops. I thought that since Intel has officially defined loads as having acquire semantics, I had eliminated the barrier requirement there. But I guess not. I suppose it's an issue worth discussing. Does anyone know offhand what C++0x implementations do for load acquires on x86?

Offhand - no. But who forbids empirical tests? :)

--8<-- main.cpp

#include <atomic>
#include <cstdint>
#include <iostream>

int test32() {
        std::atomic<int> ai(0xfacefeed);
        return ai.load(std::memory_order_acquire);
}

int64_t test64() {
        std::atomic<int64_t> ai(0xbadface00badface);
        return ai.load(std::memory_order_acquire);
}

int main(int argc, char** argv) {
        auto i1 = test32();
        auto i2 = test64();
        // Prevent dead code optimization
        std::cout << i1 << " " << i2 << std::endl;
}

-->8--

I've pulled the atomic ops into separate functions to try and prevent the compiler from being too clever.
I'm using --std=c++11 but --std=c++0x would work as well.

$ g++ -Ofast -m32 --std=c++11 main.cpp
$ objdump -d -w -r -C --no-show-raw-insn --disassembler-options=intel a.out | less -S

--8<--

08048830 <test32()>:
 8048830:       sub    esp,0x10
 8048833:       mov    DWORD PTR [esp+0xc],0xfacefeed
 804883b:       mov    eax,DWORD PTR [esp+0xc]
 804883f:       add    esp,0x10
 8048842:       ret
 8048843:       lea    esi,[esi+0x0]
 8048849:       lea    edi,[edi+eiz*1+0x0]

08048850 <test64()>:
 8048850:       sub    esp,0x1c
 8048853:       mov    DWORD PTR [esp+0x10],0xbadface
 804885b:       mov    DWORD PTR [esp+0x14],0xbadface0
 8048863:       fild   QWORD PTR [esp+0x10]
 8048867:       fistp  QWORD PTR [esp]
 804886a:       mov    eax,DWORD PTR [esp]
 804886d:       mov    edx,DWORD PTR [esp+0x4]
 8048871:       add    esp,0x1c
 8048874:       ret
 8048875:       xchg   ax,ax
 8048877:       xchg   ax,ax
 8048879:       xchg   ax,ax
 804887b:       xchg   ax,ax
 804887d:       xchg   ax,ax
 804887f:       nop

-->8--

$ g++ -Ofast -m64 --std=c++11 main.cpp
$ objdump -d -w -r -C --no-show-raw-insn --disassembler-options=intel a.out | less -S

--8<--

0000000000400950 <test32()>:
  400950:       mov    DWORD PTR [rsp-0x18],0xfacefeed
  400958:       mov    eax,DWORD PTR [rsp-0x18]
  40095c:       ret
  40095d:       nop    DWORD PTR [rax]

0000000000400960 <test64()>:
  400960:       movabs rax,0xbadface00badface
  40096a:       mov    QWORD PTR [rsp-0x18],rax
  40096f:       mov    rax,QWORD PTR [rsp-0x18]
  400974:       ret
  400975:       nop    WORD PTR cs:[rax+rax*1+0x0]
  40097f:       nop

-->8--

No barriers in sight.

Reply via email to