我有64位,我需要在事件发生之前非常快速地读取,然后在事件执行比较和交换之后。
我以为我可以在事件发生之前加载(std::memory_order_relaxed
)以便快速阅读,然后在事件发生后使用常规比较和交换。
当我比较非原子64位读取,原子(放松)和原子(获取)之间的组件时,我看不出组件中的任何差异。这是C ++测试:
int main(){
volatile uint64_t var2;
std::atomic<uint64_t> var; // The variable I wish to read quickly
var = 10;
var2 = var.load(std::memory_order_relaxed);
//var2 = var; // when var is not atomic
//var2 = var.load(std::memory_order_acquire); To see if the x86 changed
}
给这个集会:
!int main(){
main()+0: sub $0x48,%rsp
main()+4: callq 0x100401180 <__main>
! volatile uint64_t var2;
! volatile std::atomic<uint64_t> var;
! var = 10;
!
!
! var2 = var.load(std::memory_order_acquire);
main()()
main()+26: mov %rax,0x38(%rsp)
!
! int x;
! std::cin >> x;
main()+31: lea 0x2c(%rsp),%rdx
main()+36: mov 0x1f45(%rip),%rcx # 0x100403050 <__fu0__ZSt3cin>
main()+43: callq 0x100401160 <_ZNSirsERi>
!}main()+48: mov $0x0,%eax
main()+53: add $0x48,%rsp
main()+57: retq
显然使用std::memory_order_acquire
的程序集应该与非原子变量读取不同?
这是因为读取64位是原子的,只要数据是对齐的,因此汇编没有区别?我原本以为使用更强大的内存屏障会插入围栏指令还是什么?
我想知道的真正问题是,如果我将64位声明为原子并且使用宽松的内存屏障进行读取,它是否会具有与读取非原子64位变量相同的性能成本?
答案 0 :(得分:0)
如果我将64位声明为原子并且使用宽松的内存屏障读取,它是否会与读取非原子64位变量具有相同的性能成本?
是的,他们在内存障碍/围栏方面的成本相同。
在x86_64上,每个加载都具有一定的语义,因此从处理器的角度来看,具有获取语义的加载与具有宽松语义的加载相同。但它们与编译器的观点不同(宽松的操作可以与其他人重新排序)。