- 论坛徽章:
- 14
|
其实在X86平台上面,memory_order_acquire/memory_order_release最后连指令都看不到,因为X86只存在store/load reorder,其他三种乱序不存在,只要保证没有编译器优化乱序就行了。
下面所有输出均来自https://gcc.godbolt.org
- #include <atomic>
- using namespace std;
- int flag = 0;
- int data = 0;
- int foo() {
- int val = 0;
- if (flag) {
- atomic_thread_fence(memory_order_acquire);
- val = data;
- }
- return val;
- }
- void bar() {
- data = 123;
- atomic_thread_fence(memory_order_release);
- flag = 1;
- }
复制代码 x86-64 gcc 6.2 -O3 -std=c++11 -fno-verbose-asm -Wall -Wextra
- foo():
- mov eax, DWORD PTR flag[rip]
- test eax, eax
- cmovne eax, DWORD PTR data[rip]
- ret
- bar():
- mov DWORD PTR data[rip], 123
- mov DWORD PTR flag[rip], 1
- ret
- data:
- .zero 4
- flag:
- .zero 4
复制代码 x86-64 clang 3.9.0 -O3 -std=c++11 -fno-verbose-asm -Wall -Wextra
- foo():
- xor eax, eax
- cmp dword ptr [rip + flag], 0
- je .LBB0_2
- mov eax, dword ptr [rip + data]
- .LBB0_2:
- ret
- bar():
- mov dword ptr [rip + data], 123
- mov dword ptr [rip + flag], 1
- ret
- flag:
- .long 0
- data:
- .long 0
复制代码
换种写法
- #include <atomic>
- using namespace std;
- atomic<int> flag = {0};
- int data = 0;
- int foo() {
- int val = 0;
- if (flag.load(memory_order_acquire)) {
- val = data;
- }
- return val;
- }
- void bar() {
- data = 123;
- flag.store(1, memory_order_release);
- }
复制代码 x86-64 gcc 6.2 -O3 -std=c++11 -fno-verbose-asm -Wall -Wextra
- foo():
- mov eax, DWORD PTR flag[rip]
- test eax, eax
- mov eax, 0
- cmovne eax, DWORD PTR data[rip]
- ret
- bar():
- mov DWORD PTR data[rip], 123
- mov DWORD PTR flag[rip], 1
- ret
- data:
- .zero 4
- flag:
- .zero 4
复制代码 x86-64 clang 3.9.0 -O3 -std=c++11 -fno-verbose-asm -Wall -Wextra
- foo():
- mov eax, dword ptr [rip + flag]
- test eax, eax
- cmovne eax, dword ptr [rip + data]
- ret
- bar():
- mov dword ptr [rip + data], 123
- mov dword ptr [rip + flag], 1
- ret
- flag:
- .zero 4
- data:
- .long 0
复制代码
|
|