2011-05-13 124 views
7

我已經在多線程版本中實現了PageRank的一個版本。我在4核Q6600上運行它。當我運行它設置爲創建4個線程,我得到:爲什麼有更多的線程比核心更快?

real 6.968s 
user 26.020s 
sys  0.050s 

當我和128個線程運行我得到:

real 0.545s 
user 1.330s 
sys  0.040s 

這是沒有意義的我。基本算法是sum-reduce:

  1. 所有線程總和輸入的一個子集;
  2. 同步;
  3. 然後每個線程累積來自其他線程的部分結果;
  4. 主線程將所有線程的中間值相加,然後確定是否繼續。

分析沒有幫助。我不確定哪些數據有助於理解我的代碼 - 請只問。

真的讓我感到困惑。

+0

這種情況下的輸入是什麼?有什麼IO限制?你有沒有測量每個單獨的步驟? – 2011-05-13 06:02:02

+0

是否有可能有更多的線程,每個線程都得到足夠小的塊來在一個時間片內完成?有些調度系統會在第一個切片中爲線程留出一點額外時間。如果它沒有及時完成,它就會被安排並參與正常切片。如果工作被分解到真正簡單的級別,那麼您可以通過爲應用程序獲取更多切片並盜取其他進程來「遊戲系統」。你也可以嘗試以更高的優先級運行,看看你是否得到類似的結果。 – 2011-05-13 14:52:13

+0

輸入全部在開始時讀入,所以沒有IO界限。我重寫了多線程代碼的很大一部分,並刪除了一個錯誤共享的實例。虛假分享修復會稍微提高速度。 – laurencer 2011-05-14 09:39:19

回答

10

有意創建比處理器更多的線程是一種標準技術,用於利用線程被阻塞等待某些事情的「備用週期」,無論是I/O,互斥鎖還是其他通過提供其他有用工作的東西爲處理器做。

如果你的線程正在進行I/O操作,那麼這是加速的強有力競爭者:當每個線程阻塞等待I/O時,處理器可以運行其他線程,直到它們也阻塞I/O ,希望第一個線程的數據已準備好,等等。

加速的另一個可能的原因是您的線程正在經歷虛假分享。如果您有兩個線程將數據寫入同一高速緩存行上的不同值(例如,數組中的相鄰元素),則會在高速緩存行來回傳輸時阻塞CPU。通過添加更多的線程,您可以降低它們在相鄰元素上運行的可能性,從而減少錯誤共享的可能性。您可以通過向數據元素添加額外填充來輕鬆測試這些數據元素,因此它們的大小至少爲64個字節(典型的高速緩存行大小)。如果你的4線程代碼加速,這就是問題所在。

+3

關於虛假分享的猜測是非常好的。但考慮到運行時間的巨大差異,我寧願懷疑工作分區邏輯中的競爭條件錯誤,以便帶有許多線程的版本「忘記」某些工作,並且不會像其他工作那麼多。 – Ringding 2011-05-13 12:12:24

6

您可能有空閒的CPU週期,而線程會阻塞某些資源(如內存)。這些CPU週期可以被其他線程使用。我會看到的數據是... 4個線程版本是否顯示每個內核的100%利用率?如果不是,你已經找到了你的備用CPU週期。

相關問題