2016-06-13 78 views
3

Interlocked.Read(ref long)在64位體系結構上「優化」了嗎?即如果我正在編寫一個可供兩種體系結構使用的庫,我應該關注在64位CPU上不必要地使用Interlocked.Read會對性能產生的影響嗎?Interlocked.Read/Exchange在64位體系結構上長時間

我想過用這樣的事情,所以我想知道,如果這是有道理的:

// X64 is a preprocessor constant set for x64 builds 

    [MethodImpl(MethodImplOptions.AggressiveInlining)] 
    public static long Read(ref long address) 
    { 
#if X64 
     // atomic on 64-bit processors 
     return address; 
#else 
     // if I got it right, this creates a full memory barrier 
     return Interlocked.Read(ref address); 
#endif 
    } 

    [MethodImpl(MethodImplOptions.AggressiveInlining)] 
    public static void Write(ref long address, long value) 
    { 
#if X64 
     // atomic on 64-bit processors 
     address = value; 
#else 
     // if I got it right, this creates a full memory barrier 
     Interlocked.Exchange(ref address, value); 
#endif 
    } 
+0

你不應該擔心「使用'Interlocked.Read'的性能影響」 –

+0

@亨克:我認爲這是「不要過早優化」,而不是「不要優化永久,期限」。如果多個線程同時使用此代碼,我不認爲每次訪問都需要有完整的內存屏障。此外,擁有32位處理器的個人電腦已經足夠低,而且只會更低。 – Lou

+2

當然我是誇張的,但你應該真的證明這是瓶頸。我會假設Interlocked知道目標平臺的需求,並且在分析點指向它之後,只會對此感到困擾。即使我不知道你的代碼,我會說這是不太可能的。 –

回答

4

是的,你所關心的不必要的Interlocked對性能的影響,因爲Interlocked只是值上執行一個原子操作,這也保證了價值可見所有線程(順序一致)。讓我解釋。 在某些體系結構(包括一些64位體系結構)中,寫入內存位置的值可能會被緩存以提高性能。儘管是一個原子操作,只要讀取一個值可能不會讀取由另一個線程寫入的「最新」值。 Interlocked也會執行內存籬笆,以便在籬笆之前的任何操作將任何緩存的值刷新到實際內存。 所以,雖然你可能會提高性能的一小部分,你也引入潛在的競爭條件。在這不是問題的體系結構中,Interlocked不會執行額外的工作併爲您進行優化。

不幸的是,Interlocked的文檔是仍然不完全符合這些細節。請參閱http://www.albahari.com/threading/part4.aspx瞭解有關Interlocked操作涉及的圍欄的更多詳細信息。

0

我只能回答第二個問題 - 你不應該與它有關。您所能做的就是確定對變量的讀取和寫入是否需要線程安全並進行相應編碼。 C#是一種抽象 - 您正在爲語言編寫代碼,而不是處理器。編譯器和.NET框架擔心處理器。

64位讀取在64位處理器上保證是原子性的,但如您所說,您正在爲兩種體系結構編寫代碼。如果鎖定成本是您在64位體系結構中避免的顯着障礙,那麼在32位體系結構上該障礙將成爲未解決的問題。

有一個與鎖定相關的成本,但更大的成本來自不可預知的行爲,這將來自不編碼線程安全。

相關問題