2013-08-06 96 views
8

我在某處讀取互斥鎖的開銷並不大,因爲上下文切換隻發生在爭用情況下。Windows上的互斥鎖,臨界區等的代價

也稱爲Linux中的互斥體。

在Windows中,同樣的事情能保持好嗎? Critical Section是關於Linux中互斥體的更貼圖。

從我收集的數據看,臨界區與Mutex相比提供了更好的最佳性能,對於每種情況都是如此?

在Windows中是否存在互斥體比關鍵部分快的情況。

假設只有一個進程線程訪問的互斥(只是爲了消除臨界區的其他利益)

新增信息:操作系統windows服務器,
語言C++

+0

當然,如果您的應用程序頻繁爭用,您可能會重新考慮互斥鎖沒有太多開銷的想法。 – patrickvacek

回答

12

考慮的具體目的Critical SectionsMutexes我不認爲你可以問一個關於成本的問題,因爲當你需要多個線程觸摸相同的數據時,你沒有太多的選擇。顯然,如果你只需要增加/減少一個數字,你可以在volatile號碼上使用Interlocked*()函數,你很好。但對於更復雜的任何事情,您需要使用同步對象。

Synchronization Objects available on Windows^開始您的閱讀。所有功能都列在那裏,很好地分組和正確解釋。 有些僅限於Windows 8。

作爲關於你的問題,Critical Sections是因爲它們都設計在同一流程操作長於Mutexe便宜些。閱讀this^this^或只是下面的引用。

臨界區對象提供與由互斥對象提供的類似的同步,區別在於臨界區只能由單個進程的線程使用。事件,互斥體和信號量對象也可用於單進程應用程序,但關鍵節對象爲互斥同步(特定於處理器的測試和設置指令)提供了一個更快,更高效的機制。像互斥對象一樣,臨界區對象一次只能由一個線程擁有,這對保護共享資源免受同時訪問很有用。與互斥對象不同,無法判斷臨界區是否被放棄。

我使用Critical Sections爲相同的處理同步和Mutexes用於交叉處理的同步。只有當我真的需要知道一個同步對象是否被放棄時,我在同一個進程中使用Mutexes。

所以,如果你需要一個同步對象,這個問題是不是有什麼成本,而且更便宜:)真的沒有辦法,只好內存損壞。

PS:有可能是這樣的one mentioned in the selected answer here^辦法,但我總是去與跨platformness核心特定平臺功能。它總是更快! 所以,如果你使用的是Windows,使用Windows :)的工具

UPDATE

根據您的需求,您可能能夠通過嘗試做盡可能多的自我,以減少同步對象的需要包含在一個線程中的工作儘可能,並且只在最後或每隔一段時間組合數據。

愚蠢示例取一個網址列表。你需要刮他們並分析他們。

  1. 拋出一堆線程,從輸入列表中開始逐個挑選URL。對於每一個你的過程,你都會集中處理結果。這是真正的時間和很酷
  2. 或者你可以拋出他們每個人都有一部分輸入網址的線程。這消除了同步選擇過程的需要。您將分析結果存儲在線程中,最後將結果合併一次。或者每10個URL就說一次。不是每個人。這將顯着減少同步操作。

因此,通過選擇正確的工具並考慮如何降低鎖定和解鎖,可以降低成本。但成本不能被刪除:)

PS:我只是想在網址:)

更新2:

曾在一個項目需要做一些測量。而結果相當令人吃驚:

  • 一個std::mutex是最昂貴的。 (跨platformness的價格)
  • 一個Windows本地Mutexstd快2倍。
  • A Critical Section本地Mutex快兩倍。
  • A SlimReadWriteLockCritical Section的+ -10%。
  • 我自制InterlockedMutex(自旋鎖)爲1.25倍 - 比Critical Section快1.75倍。
+0

我知道我無法消除成本,但只是在考慮臨界區或互斥對我而言是否理想。感謝您的信息,但 –

+0

@DesertIce發佈了更新。最後它是正確的。 – CodeAngry

+1

-1爲易變。你永遠不應該依賴易失性來進行線程化。要麼使用原子,要麼將volatile與內存隔離結合起來。否則,例如,您的易失性訪問最終可能會在Linux/gcc上重新排序。 –

0

使用的std ::在Windows 8上互斥我通常用我自己定製的自旋鎖獲得3-4倍的改進(在非百家爭鳴的情況下)加速:

基於互斥

auto time = TimeIt([&]() { 
for (int i = 0; i < tries; i++) { 
    bool val = mutex.try_lock(); 
    if (val) { 
     data.value = 1; 
    } 
} 

});

自制的無鎖

time = TimeIt([&]() { 
    for (int i = 0; i < tries; i++) { 
     if (!guard.exchange(true)) { 
      // I own you 
      data.value = 1; 
      guard.store(true); 
     } 
    } 
}); 

測試是在x86製成。

我還沒有想出std :: mutex在windows上使用下劃線,因爲它會產生大量的代碼。