2010-06-30 87 views
6

我有一個Java應用程序,它有一個固定的十五個線程池,機器Solaris 10 SPARC有十六個CPU。添加池大大提高了性能,但是我想知道池中是否有太多的線程。如果線程數量較少,或者Solaris在線程調度方面做得很好,性能會更好嗎?什麼是Java線程與Solaris上的CPU的良好比例?

假定池大量使用15個CPU,然後其他應用程序線程因各種原因需要CPU,併發垃圾收集就是一個很好的例子。現在,池和其他應用程序線程之間共享五個CPU。然後CPU從1到7變得免費,Solaris會將繁忙CPU上的線程共享時間移動到空閒的CPU上?

如果沒有,最好是保持池大小更小,以便其他應用程序線程總是有空閒的CPU。使問題更復雜化的是,應用程序中的CPU使用率非常零星。

+0

@paxdiablo:哦,謝謝你的編輯,我正在摸索着弄清楚「Solaris 10 Spark」是什麼...... @KaizenSoze:每個CPU有多少個內核? @SO社區:核心線程與性能分析的關係不大? – bakkal 2010-06-30 12:34:45

+0

感謝您的好評。我應該在原來的問題中加入,不涉及IO,它是CPU密集型的過程。 – KaizenSoze 2010-06-30 13:46:26

回答

4

如果只執行cpu密集型任務(無IO)N + 1個線程(其中N是內核數量)將爲您提供最佳的處理器利用率。
+1,因爲你可以有一個頁面錯誤,在同步過程中可以暫停Therad以任何理由或很短的等待時間。

對於線程做IO這不是很容易,你必須測試最佳的大小。
書中Java concurrency in practice表明該算法作爲起點:

N = number of CPUs 
U = target CPU utilization (0 <= U <= 1) 
W/C = ration of wait time to cpu time (measured through profiling) 

threads = N * U * (1 + W/C) 

IBM使用相同的算法在他們的文章Java theory and practice: Thread pools and work queues,具有固定的U = 1。 IBM文章中的N + 1事實也可以被讀取,以爲這兩個論文提供起源。

-3

通常,如果您可以在線程和CPU之間建立1對1映射,您將獲得最佳性能。這是假定用戶線程與內核線程1對1映射。如果我沒有記錯,Solaris允許多個內核線程以及用戶線程,所以在這方面你應該沒問題。當多個線程使用相同的CPU時,會遇到瓶頸。

與往常一樣,針對減少線程池大小問題的最佳建議是:「嘗試並基準化它。」 (但我懷疑在這種情況下會更好。)

至於你關於其他正在運行的應用程序的問題,Solaris將使用CPU在你的線程池和其他應用程序之間進行切換。如果CPU變空閒,Solaris會將一些線程移動到空閒的CPU。

編輯:Here是Sun關於Solaris和Java線程模型如何交互的鏈接。

+0

-1:有時會阻塞IO的應用程序比每個CPU有超過1個線程可提高性能的應用程序要比看到由於線程太多而導致的實際性能瓶頸更爲常見。 – 2010-06-30 12:24:19

1

擁有比CPU更多的線程通常很好,這實際上可以幫助整體吞吐量。

其原因是多個線程可能在IO上被阻塞或在任何給定時間處於睡眠狀態。所以準備執行幾條線程永遠不會受傷。

+0

p.s.還有一點就是現在的線程開銷很小,除了緩存一致性的影響之外,保持線程數減少的實際優勢很小。 – mikera 2010-06-30 12:19:11

+0

使用線程的主要成本是軟件的複雜性,因爲突然間你不得不考慮併發性。 – samoz 2010-06-30 12:20:08

+2

@samoz - true,但無論您使用2,16或1000線程,「思考複雜度」成本大致相同。幾乎所有的線程安全問題都是一個簡單的二元事情,它依賴於*多於一個*線程。這是一個不尋常的問題,將總是與32個線程一起工作,但會(可能)與33個或更多的... – 2010-06-30 13:08:10

相關問題