2010-04-08 32 views
3

我有一個程序啓動並創建一個內存中的數據模型,然後創建一個(命令行指定的)線程數,以針對輸入集和該數據模型運行多個字符串檢查算法。工作在輸入字符串集中的線程之間進行劃分,然後每個線程迭代相同的內存數據模型實例(不再更新,因此沒有同步問題)。爲什麼我的多線程Java程序不能最大化我的機器上的所有內核?

我在帶有2個quadcore處理器的Windows 2003 64位服務器上運行它,並且從查看Windows任務管理器,它們沒有被超出,(它們也沒有看起來像是特別徵稅)當我運行10個線程。這是正常的行爲嗎?

看來,7個線程都完成了類似的時間量類似的工作量,所以,你會推薦7個線程,而不是運行?

我應該有多個線程運行呢?......雖然我認爲這可能是有害的,因爲JVM將做更多的上下文中的線程之間的切換。

或者,我應該用更少的線程運行它嗎?

另外,什麼是我可以用來衡量這個最好的工具?......一個分析工具是否會幫助我在這裏 - 事實上,這是幾個分析器之一更好地檢測瓶頸(假設我在這裏有一個)比其他的?

注意,服務器也運行SQL Server 2005(這可能會或可能不相關),但沒有什麼是發生該數據庫上,當我運行我的程序。

還要注意,線程只是做字符串匹配,他們沒有做任何I/O或數據庫的工作或其他任何他們可能需要等待。

+3

它真的是quadcore,還是隻有4個邏輯處理器與HT(2核心,每個2線程)? – Lucero 2010-04-08 15:24:56

+0

@Lucero,我怎麼能說出來?該服務器是IBM X3400,採用2枚Xeon E5320 1.86 GHz芯片。我相信他們是quadcore,我也只是看了一下wikipedia - http://en.wikipedia。org/wiki/Xeon - 我認爲這證實了它,但是如果這些是E5320,那麼很高興能被證明,否則 – 2010-04-08 15:33:18

+1

,那麼你沒有HT支持,我的評論並不重要。使用HT時,CPU基本上保持每個內核有兩個線程上下文,因此,如果線程停頓(例如,在內存訪問等情況下),並且因爲HT配置中的純計算能力不同於其他線程,兩個真正的核心 – Lucero 2010-04-08 16:14:30

回答

2

沒有看到實際的代碼,很難給出適當的建議。但是確保線程沒有鎖定在共享資源上,因爲這自然會阻止它們儘可能高效地工作。另外,當你說他們沒有做任何io時,他們是不是正在讀輸入或寫輸出?這也可能是一個瓶頸。

關於cpu密集線程,運行更多的線程通常不會比實際內核多,但是在像這樣的非受控環境中,與其他大型應用程序同時運行,您可能更適合簡單地測試通往最佳線程數的途徑。

+0

@kasperjj - 很公平的,代碼有點難以分開展示一個簡潔的例子,線程最終會寫入一個單獨的輸出到一個文件(一個文件每個線程),但這是非常小的IO。是否有線程可以鎖定共享資源沒有任何明確的同步我已經指定的機制? – 2010-04-08 15:26:44

+1

我特別想到像共享結果文件,但顯然你有覆蓋:-) 您可能還想確保您沒有使用任何同步數據結構,如Vect要麼。 – kasperjj 2010-04-08 15:32:14

+0

謝謝,我使用的數組,集合和ArrayLists我可以 – 2010-04-08 15:42:27

5

我的猜測是,您的應用程序的瓶頸在內存訪問,也就是你的CPU內核花費大部分時間等待數據從主內存中讀取。我不確定配置文件能夠很好地診斷這類問題(配置文件本身可能會大大影響行爲)。您可以通過讓代碼在非常小的數據集上重複執行多次操作來驗證猜測。

如果這個猜測是正確的,你唯一可以做的(不是讓更多的內存帶寬,服務器等)是嘗試和增加你的內存訪問,以更好地利用高速緩存的地方;但取決於不可能的應用程序的細節。由於核心共享高速緩存,因此使用更多線程實際上可能會導致性能下降。

+0

和B先生一樣,你給了我一些思考和消化一下,謝謝! – 2010-04-08 15:35:04

+0

@Michael如果是這種情況,線程可以共享內存的唯一一點就是共享數據集。如果我將字符串克隆到每個線程的數組列表中(或者甚至執行'new String(inputString)'以確保它們不是常量池中的同一個引用),那麼是否可以消除這種瓶頸? – 2010-04-08 16:18:37

+0

@James B:不,這會讓線程將數據集的副本從緩存中推出來,從而使問題變得更糟。只要不需要同步,共享數據集就是*好*。 – 2010-04-08 20:51:19

相關問題