2013-10-03 26 views
2

http://blog.memsql.com/common-pitfalls-in-writing-lock-free-algorithms/的末尾,David Stolp顯示了無鎖定堆棧的性能數據,表明無鎖定版本比由互斥鎖保護的順序版本慢,即使爭用增加。結果很有意思,但有兩件事關注我:http://tinyurl.com/pzpyvb9上的無鎖棧性能數據是否現實?

  • 充其量,隨着線程數量的增加,「總體吞吐量」減少並逐漸消失。隨着線程數量的增加,整體吞吐量不應該增加嗎?
  • 在最終圖表中,1線程的性能值範圍從35M到55M左右。對於1個線程來說,這看起來非常寬泛(不存在任何爭用)。

我試圖找到一種方法來聯繫作者關於這些問題,但我沒有成功,所以我轉向SO社區,看看結果是否看起來很現實。他們呢?

+0

正如我所看到的互斥體版本si最慢。 –

+0

@GJ:從我所知道的情況來看,基於互斥體的版本與「天真」無鎖版本(每個最終圖表)基本相同(緩慢)。可能會有點慢,但是,你是對的。但是,這不會影響線程數增加或單個線程的吞吐量值範圍很寬的吞吐量問題。 – KnowItAllWannabe

回答

1

充其量,隨着線程數量的增加,「總體吞吐量」減少,然後逐漸減小。總線吞吐量不應該增加爲 線程數量增加了嗎?

這很規範!堆棧只有一個!瓶頸是線程之間的內存同步,而不是代碼執行。因此,如果更多的線程填滿堆棧,則應該發生更多的內存衝突(競爭條件出現),因此吞吐量會下降。

在最終圖表中,1線程的性能值範圍從 約35M到55M。這似乎是1線程 (其中不存在任何爭用)非常廣泛的範圍。

這個測試代碼是不現實的,因爲它只是彈出並將節點推入堆棧。因此,相對較短的代碼的最小差異會顯着影響吞吐量。

如果檢查代碼比你可以看到自旋鎖的版本是非常簡單,因爲與test_and_set原子功能是normaly比原子CAS快這是在LockFree使用(比較和交換)發可能比LockFree更快版。

編輯:

在LockFree版本用於cmpxchg16b其在自旋鎖16字節CAS僅使用8字節test_and_set功能(帶cmpxchg8b實現),以使速度差存在!

+0

如果測試代碼在堆棧操作之間做了一些工作(例如,爲堆棧準備一個對象,然後按下它;彈出一個元素後,做一些工作),我們預計吞吐量會隨着線程數量增加了吧?另外,我是否正確地下載了基準代碼並查看了它? – KnowItAllWannabe

+0

@KnowItAllWannabe:檢查代碼如何爲LockFree和SpinLock創建線程安全的程序堆棧。在LockFree版本中使用'cmpxchg16b'這是16字節CAS在SpinLock中僅使用8個字節CAS cmpxchg8b因此存在速度差異! –

+0

我將此標記爲公認的答案,因爲它是第一個出現的。 David Hammen的回答基本上是一樣的,儘管它更易於閱讀。 – KnowItAllWannabe

1

充其量,隨着線程數量的增加,「總吞吐量」減少,然後逐漸消失。隨着線程數量的增加,整體吞吐量不應該增加嗎?

不一定,在這種情況下絕對不是。如果執行的線程可以同時運行,多線程是有益的。如果線程永遠不能併發運行,或者幾乎所有的執行都涉及單個資源的爭用,那麼最好讓應用程序單線程化。

此測試的設計使線程不能同時運行。幾乎所有的代碼都爭奪一個資源,一個堆棧。這個名義上不好的設計在這裏被有意使用,以便測試各種併發執行方案的開銷費用,並測試各種方案處理爭用的情況。

在最終的圖表中,1線程的性能值範圍從35M到55M左右。對於1個線程來說,這看起來非常寬泛(不存在任何爭用)。

即使沒有爭用,鎖定和解鎖互斥鎖也會涉及很多開銷。比較和交換的開銷要少得多,在測試和設置時更少。純粹的開銷是當只有一個執行線程時正在測試的內容。