2012-10-15 65 views
2

我實現了一個引用計數模式,爲此我需要互鎖功能但沒有內存隔離(據我瞭解)。如何實現沒有內存障礙的InterlockedIncrement

不幸的是,只有Windows有一個InterlockedDecrementNoFence編譯器。 我如何使用asm內聯做到這一點?我也需要這個gcc/clang。

+0

嗯...內聯彙編會在MSVC和gcc是不同的......反正和阻擋更好保持原來的位置。 –

回答

1

對於這個操作的語義來說,缺少至少一個內在的內存圍欄操作(取決於平臺)幾乎是不可能的。爲了使原子增量/減量工作,另一個處理器必須保證在對變量執行自己的操作之前查看原子操作的值,並且操作對變量的可見性必須具有一定的保證總數訂購。內存障礙,即使是像x86這樣的強存儲器模型(其中標準內存操作獲取/釋放語義)等隱式障礙,對於原子增量/減量操作的正確性也是至關重要的。請記住,即使MSVC/gcc的文檔說存在內存障礙,在x86上也不會有實際的內存障礙應用(即MFENCE指令),這是由於強記憶模型該平臺,而是鎖定存儲器總線以確保操作的原子性。另一方面,由於該平臺的內存模型較弱,IA64需要內存屏障。 ARM也是如此。

+0

所以我沒有理解障礙的概念。因爲我認爲它只會影響等待不同讀/寫操作的順序。由於只涉及一個內存位置,因此根據refcounting完全沒有訂購問題。在多處理器系統的情況下,緩存一致性協議已經解決了這個問題。 – Lothar

+0

請記住,我說「內在」障礙...取決於平臺可能沒有明確的內存障礙操作,但你仍然支付罰款 - 如果有一個,因爲你必須做出原子操作的結果每個其他處理器都可以看到,並且每個原子操作必須在給定的內存地址上有一個總的順序。 – Jason

1

這不是一個直接的答案,而是一個替代方案。如果您可以使用C11(或C++ 11),那麼如何使用memory_order_relaxed進行原子操作?您的編譯器可能會在弱內存模型平臺上生成無內存柵欄。 (這取決於編譯器供應商/版)

#include <stdatomic.h> 

atomic_int var; 
int oldval; 

oldval = atomic_fetch_sub_explicit(&var, 1, memory_order_relaxed);