2013-09-25 21 views
4

在Intel x86/x86_64系統中有三種類型的內存障礙:隔離,保護和防護。在使用方面的問題。 對於需要SC語義的所有存儲器單元而言,對於順序語義(SC)足以使用MOV [addr], reg + MFENCE。但是,您可以在整體中編寫代碼,反之亦然:MFENCE + MOV reg, [addr]。顯然感覺到,如果存儲器的存儲數量通常小於存儲器的存儲容量,那麼使用寫入存儲器的總成本要低一些。在此基礎上,我們必須使用順序存儲器來進行存儲,並進行了另一種優化 - [LOCK] XCHG,由於「XCHG內部的MFENCE」僅適用於內存中使用的緩存行XCHG(video where on 0:28:20 said that MFENCE more expensive that XCHG)。爲什麼x86/x86_64上的Sequential Semantic通過MOV [addr],reg + MFENCE而不是+ SFENCE使用?

http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

C/C++ 11操作86執行

  • 負載Seq_Cst:MOV(從存儲器)
  • 商店SEQ Cst中:(LOCK)XCHG // 替代: MOV(進入存儲器),MFENCE

注:有的C/C++ 11〜86的替代映射,而不是鎖定(或擊劍)的SEQ Cst中存儲的鎖,其/圍欄的SEQ Cst中負載:

  • 負載Seq_Cst:LOCK XADD(0)//選擇:MFENCE,MOV(從內存中)
  • 商店SEQ Cst中:MOV(到內存)

不同的是,ARM和斷電記憶障礙與LLC專門交互(最後Level Cache)和x86進行交互,並與較低級別的緩存L1/L2進行交互。 在86/x86_64的:

  • lfence上核心-1:(COREX-L1) - >(COREX-L2) - > L3->(核心-1-L2) - >(核心-1-L1)
  • sfence上核心-1:(核心-1-L1) - >(核心-1-L2) - > L3->(COREX-L2) - >(COREX-L1)

在ARM:

  • ldr; dmb;:L3- >(Core1-L2)→(Core1-L1)
  • dmb; str; dmb;:(核心-1-L1) - >(核心-1-L2) - > L3

C++ 11代碼由GCC 4.8.2編譯 - 在GDB x86_64的:

std::atomic<int> a; 
int temp = 0; 
a.store(temp, std::memory_order_seq_cst); 
0x4613e8 <+0x0058>   mov 0x38(%rsp),%eax 
0x4613ec <+0x005c>   mov %eax,0x20(%rsp) 
0x4613f0 <+0x0060>   mfence 

但爲什麼在x86/x86_64序貫語義(SC)使用通過MOV [addr], reg + MFENCE而不是MOV [addr], reg + SFENCE,爲什麼我們需要全圍欄MFENCE而不是SFENCE呢?

+0

我認爲商店圍牆只會與其他商店同步,而不會與其他商店同步。順序一致性意味着您需要所有CPU都能觀察到的* total *順序,並且商店柵欄不會暗示多個商店的順序。 –

+0

@Kerrek這對於ARM來說是正確的,但對於x86來說不是這樣,因爲如果我們在第一個CPU內核上創建SFENCE,那麼在訪問這個內存單元之前,我們不再需要在另一個CPU內核上執行LFENCE。因此,如果所有的變量都需要順序語義(SC),我們做SFENCE,而且我們不需要在任何地方有LFENCE。還是你的意思是MFENCE取消了處理器流水線中兩個方向的重新排序(無序執行)? – Alex

+0

首先,我想我想說的是,單獨的保護不能提供被所有CPU所迷惑的* total *排序... –

回答

0

你不需要mfence; sfence確實足夠。事實上,除非您正在處理設備,否則在x86中您從不需要lfence。但是英特爾(和我認爲AMD)已經(或者至少已經)與mfencesfence(即刷新存儲緩衝區)共享一個單獨的實現,因此使用較弱的sfence沒有性能優勢。

順便說一句,請注意,每次寫入共享變量後,您都不必刷新;您只需在寫入操作和後續讀取其他共享變量之間進行刷新。

+0

謝謝!但我不同意這一點 - 我「從不需要在x86中保護」。你可以看到我對此的補充問題,並查看我們可以在哪裏使用它「3. MFENCE + LOAD和STORE(無圍欄)」http://stackoverflow.com/q/19047327/1558037我沒有把任何圍欄放在任何地方,但它爲每個std :: memory_order_seq_cst(Sequential Semantic Variable)執行C/C++編譯器, – Alex

相關問題