这似乎是映射,至少在使用英特尔编译器编译的代码中,我看到:
0000000000401100 <_Z5storeRSt6atomicIiE>:
401100: 48 89 fa mov %rdi,%rdx
401103: b8 32 00 00 00 mov $0x32,%eax
401108: 89 02 mov %eax,(%rdx)
40110a: c3 retq
40110b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000401110 <_Z4loadRSt6atomicIiE>:
401110: 48 89 f8 mov %rdi,%rax
401113: 8b 00 mov (%rax),%eax
401115: c3 retq
401116: 0f 1f 00 nopl (%rax)
401119: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
对于代码:
#include <atomic>
#include <stdio.h>
void store( std::atomic<int> & b ) ;
int load( std::atomic<int> & b ) ;
int main()
{
std::atomic<int> b ;
store( b ) ;
printf("%d\n", load( b ) ) ;
return 0 ;
}
void store( std::atomic<int> & b )
{
b.store(50, std::memory_order_release ) ;
}
int load( std::atomic<int> & b )
{
int v = b.load( std::memory_order_acquire ) ;
return v ;
}
当前的英特尔架构文档第 3 卷(系统编程指南)很好地解释了这一点。看:
8.2.2 P6 和最新处理器系列中的内存排序
- 读取不会与其他读取重新排序。
- 写入不会与较旧的读取一起重新排序。
- 对内存的写入不会与其他写入重新排序,但以下情况除外: ...
那里解释了完整的内存模型。我假设英特尔和 C++ 标准人员已经详细合作,为每个可能的内存顺序操作确定了最佳映射,该映射符合第 3 卷中描述的内存模型,并且已经确定了普通存储和加载在这些情况下就足够了。
请注意,仅仅因为 x86-64 上的这个有序存储不需要特殊说明,并不意味着这将是普遍正确的。对于 powerpc,我希望在 store 中看到类似 lwsync 的指令,而在 hpux (ia64) 上,编译器应该使用 st4.rel 指令。