2012-02-20 141 views
3

使用YourKit,我測量了一個應用程序,並確定了主CPU接收器。我通過具有固定數量的線程的ExecutorService對結構化計算進行並行化。在java中跟蹤線程衝突

在一個24核的機器,增加線程的好處步道關閉速度非常快以上4。所以,我想,一定是有競爭或鎖定事情在這裏,或IO延遲,或什麼的。

OK,我打開YourKit的「監控使用」功能,並在工作線程表現出的阻塞時間量是微不足道的。目光看線程狀態圖,工作線程幾乎都是「綠色」(運行),而不是黃色(等待)或紅色(阻止)。

CPU分析仍顯示在調用樹是工作線程內96%的時間。

所以有些東西正在實時使用。它可能是調度開銷?

在僞代碼,你可能對此建模:

loop over blobs: 
    submit tasks for a blob via invokeAll of executor 
    do some single-threaded processing on the results 
end loop over blobs 

在試運行中,有〜680點的斑點,並〜13個任務/斑點。所以每個線程(假設四個)每個blob發送約3次。

硬件:我已經在我的MacBook Pro運行在一個小規模的測試,然後在一個大胖子戴爾:在Linux上HWINFO有報道爲--cpu 24名不同的項目中,

Intel(R) Xeon(R) CPU   X5680 @ 3.33GHz 

組成英特爾的網站告訴我,每個核心都有6個核心,12個線程,我懷疑我有4個核心。

+1

的invokeAll因爲等待所有任務的完成,是有可能的任務是不同的大小?說blob A有6個任務,但其中一個需要5倍的時間。使用1個線程,運行時間爲10,2:5(5,1 * 5),3:5(5,1x3,1x2)。因此沒有更多的性能優勢,因爲通過短任務咀嚼的額外線程,但blob單線程仍在等待長跑者。 – Thomas 2012-02-20 20:35:29

+0

如果是這樣,我會看到一些在線等待,我有理由懷疑我有高杆。 – bmargulies 2012-02-20 21:43:37

回答

2

假設你有4芯與每個8個邏輯線程,這意味着你有可跨32個線程共享4真正處理單元。這也意味着當你在同一個內核上有2-8個活動線程時,它們必須爭奪CPU管道,指令和數據高速緩存等資源。

這個工作最好,當你有這必須等待像磁盤或網絡IO外部資源的線程。如果您有CPU密集型進程,您可能會發現每個內核一個線程將使用您擁有的所有CPU能力。

我寫了一個庫,它支持linux和windows的線程和內核的分配。如果你有Solaris,它可能很容易移植,因爲它支持JNI posix調用和JNA調用。

https://github.com/peter-lawrey/Java-Thread-Affinity

+0

請參閱我的編輯。我在Linux上,你的東西應該直接適用。 – bmargulies 2012-02-20 23:14:45

1

這很可能不是爭論,雖然很難說沒有更多的細節。性能分析結果可能會引起誤解,因爲Java在磁盤或網絡I/O上阻塞時將線程報告爲RUNNABLE。 Yourkit仍將其計爲CPU時間。

最好的辦法是打開CPU剖析和深入到什麼抽空在工作線程。如果它主要在java.io類中結束,那麼您仍然存在磁盤或網絡延遲。

0

您還沒有完全並行處理。您可能不會提交下一個blob,直到前一個blob的結果完成,因此不會進行並行處理。

如果可以的話,試試這個方法:

for each blob{ 

     create a runnable for blob process name it blobProcessor; 
     create a runnable for blob results name it resultsProcessor; 
     submit blobProcessor; 
       before blobProcessor finishes, submit resultsProcessor; 
} 

也:

請看看JetLang提供使用纖維的螺紋併發。

+0

並非如此。大量的並行處理正在發生。並行化區域的總體工作遠遠大於其他部分。 – bmargulies 2012-02-20 21:42:55