簡體   English   中英

.load(std :: memory_order_relaxed)的成本與讀取非原子變量的成本相同嗎?

[英]Does .load(std::memory_order_relaxed) cost same as reading unatomic variable?

我有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位聲明為atomic並且使用寬松的內存屏障讀取,那么它的性能成本是否與讀取非atomic 64位變量相同?

如果我將64位聲明為原子位並且使用寬松的內存屏障讀取,那么它的性能成本是否與讀取非原子64位變量相同?

是的,它們在存儲屏障/圍欄方面的成本相同。

在x86_64上,每個負載都具有aqcuire語義,因此從處理器的角度來看,具有獲取語義的負載與具有寬松語義的負載相同。 但是從編譯器的角度來看它們是不同的(放松的操作可以與其他操作重新排序)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM