2016-08-07 95 views
0

我最近碰到這個問題就來了一個評估:線程池的大小應該達到最大性能?

ExecutorService threadpool = Executors.newFixedThreadPool(N); 

for(Runnable task : tasks){ 
    threadpool.submit(task); 
} 

每個任務花費的計算爲25%和75%執行I/O。假設我們正在研究四核機器(無超線程),線程池N的大小應該是多少以達到最大性能而不浪費線程? (假設我們有無限的I/O容量)

我猜測16是因爲機器有無限的I/O意味着我們可以完全專注於CPU。每個任務在運行時使用四分之一的CPU。這意味着,我們可以運行四個任務來飽和一個CPU內核,並使四核機器上的N = 16。

更新:此題的選項分別爲2,4,5,6,7,8,12和16

+3

你的答案是什麼,你是怎麼想出來的,你爲什麼不認爲這是正確的答案? – Andreas

+0

我的回答是16,因爲這臺機器有無限的I/O意味着我們可以完全專注於CPU。每個任務在運行時使用四分之一的CPU。這意味着,我們可以運行四個任務來飽和一個CPU內核,並使四核機器上的N = 16。 – Mickey

+0

聽起來像是對我的正確答案。 – Andreas

回答

0

你是正確的,你應該考慮你的飽和核。不過,最好的答案將超過16個。如果你只有16個線程,那麼CPU的需求就不會完全對齊,這樣你所有的內核都會一直在使用。

所以最好的答案是> 16,也足夠小,不會顯著提高個人任務完成時間,並處顯著線程轉換成本,或浪費一大堆的內存。

如果你在課堂上學到了這一點,那麼你的教授可能會給你乘數作爲「經驗法則」。他會期待你記住它並將它應用到這裏。

我通常使用average_demand = 2 * num_cores,所以會選擇32個線程。這在大多數情況下運作良好。當平均CPU需求是核心數量的兩倍時,核心利用率將接近100%。

而且,在這種情況下,每個任務的CPU部分只得到平均1/2的核心,因此它需要兩倍的時間......但這樣的任務完成時間只有13它是工作的只有25% %超過最佳。

2倍的默認,我用差不多比最佳人數始終較高,但它也幾乎總是足夠低,不徵收額外顯著開銷。如果你知道你的任務的CPU限制很大,那麼你可以自信地減少這個數字。

如果你真的想找到最佳值,那麼你可以測量它,但是當你在正確的範圍內它不會產生很大的差異。

-

P.S注:「average_demand」我上面使用是芯,這將是在使用中在任何時候給定N個線程和N個核的預期數量。

1

雖然這個問題沒有嚴格的對錯,主觀好的是:

32個線程

你必須考慮從概率上。 現在讓我們考慮一個CPU核心和獨立線程:

一個線程在任何給定時間有25%的機會做計算。 如果你有2個獨立的線程(概率事件),至少有一個CPU做一些工作的概率不是50%,而是7/16(43.75%)。(如果您對此不確定,則應刷新其中一些probability skills)。

你可能會看到這是怎麼回事。對於P爲100%,線程數必須是無限的。所以我們必須做出有根據的猜測:4個線程的P爲〜68%,8個線程爲〜90%。增加數量現在真的沒有什麼效果,所以我們定在8點。這是一個核心。我們有4個CPU核心,所以我們可以乘以4,我們得到最終答案:32.