簡體   English   中英

可以使用Interlocked.CompareExchange嗎?

[英]Possible to use Interlocked.CompareExchange with a Bit?

我有一個整數數組,該整數數組可以跟蹤10,000個並發任務的完成,其值為1或0。我認為,如果此數組是一個Bits數組,並且每個並發線程使用互鎖,則效率會更高。 )更改一位。

如果“互鎖”沒有“位”的重載,我應該如何處理?

您可以在一個循環中使用Interlocked.CompareExchange(ref int, int, int)進行偽造,但我認為這樣做不會更有效:

private static void SetBit(ref int valueToUpdate, int bitToSet)
{
   while (true)
   {
      int oldValue = valueToUpdate;
      int newValue = oldValue | bitToSet;
      int result = Interlocked.CompareExchange(ref valueToUpdate, newValue, oldValue);
      if (result == oldValue) break;
   }
}

我不認為您可以使用Interlocked使用位。 我相信,您將不得不切換到一個ints數組,以便每個位都在其自己的int

Interlocked.CompareExchange僅比較是否相等,而您只需要比較該int一小部分,除非您使用其他並發策略來保護該int所在的int的其他更改,否則您無法進行比較。

您需要線程安全的構造來跟蹤並發任務的完成。 因此,互鎖的構造總是比鎖快(因為它們不需要鎖),因此您應該使用Interlocked -class中的帶有整數的靜態方法(例如,0等同於false ,1等同於true )。

傑弗里·里希特(Jeffrey Richter)所做的與他在第28章“原始線程同步構造”中的“通過C#進行CLR”中的描述相同。 他還在Wintellect.PowerThreading庫中介紹了基於互鎖結構的自己的鎖實現,並對自己的實現以及.net框架中的實現進行了出色的解釋以及時間比較。

首先,不,所有互鎖功能都在存儲器地址上運行,並且單個位不可尋址。

那么該怎么做呢?

我將研究兩個選擇:

  • 根本不用理會數組:擁有一個簡單的計數器,並在每次任務完成時對其進行InterlockedIncrement 要查看所有任務是否已完成,只需檢查該值是否已達到10,000。
  • 或者,使用數組,以最小化(錯誤)數據共享。 但是,您不應該嘗試將其密集包裝。 相反。 確保每個條目最終都位於單獨的CPU高速緩存行上,以便並行運行的任務不會爭奪相同的高速緩存行。 (然后,由於所有任務都寫入不同的位置,因此它們甚至不必通過昂貴的互鎖操作來設置“完成”標志。)

我不知道哪一個最快。 如果性能很重要,請進行基准測試。 :)

暫無
暫無

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

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