Venkat Subramaniam 博士在《Programming Concurrency on the JVM》中提到關於最優線程數的計算:程序員
The minimum number of threads is equal to the number of available cores. If all tasks are computation intensive, then this is all we need. Having more threads will actually hurt in this case because cores would be context switching between threads when there is still work to do. If tasks are IO intensive, then we should have more threads. We can compute the total number of threads we’d need as follows:測試
Number of threads = Number of Available Cores / (1 - Blocking Coefficient)this
To determine the number of threads, we need to know two things:
• The number of available cores
• The blocking coefficient of tasks線程
根據描述,最佳線程數量=CPU執行核心數/(1-阻塞係數);ci
許多程序員就立馬寫個程序測試,模擬一個阻塞係數0.5的線程,硬件配置CPU執行核心數是4,剛好2倍核心數,最佳線程數量是8,而後就開8個線程去處理。測試完成任務處理時間是316ms。覺得這樣是最佳了。而後又抱着懷疑的態度再作一輪測試,特地開16個線程去一跑,發現時間只用了215ms。更少了。咦?怎麼回事呢?而後得出結論:最佳線程數量並不是最佳。 4倍纔是最佳的。是這樣嗎?問題出在哪裏了呢?產品
其實,若是全系統只運行你一個程序,只考慮測試代碼,阻塞係數是0.5,固然是沒錯的,可是這個公式是針對全系統而言的,須要把全系統全部程序的線程佔用的timeslice都計算在內考慮。理論計算是須要考慮全部細節的,這些細節佔用的時間可一點很多。it
當全系統線程數量遠遠大於執行核心數,則增長了線程的上下文環境交換時間等等,還有其餘線程分走了許多CPU時間片,這部分時間可很多,但是卻沒有用在你的測試計算上。爲簡化理解,直接把這部分時間都划算到阻塞時間上,等於說阻塞係數變大,純工做係數變小;分母就變小了,最佳線程數量就成倍增大了。io
若是還不理解,我舉個例子,用實際場景來解釋就明白了。thread
一個加工廠有4條加工流水線,每個人同時只能佔用一條流水線加工本身的產品,假定一我的佔據一條加工流水線徹底飽和工做8小時能完成本身的加工,那麼拆分到4條線上顯然2小時能夠加工完成,理論上。配置
再假定人的飽和工做時間和空閒時間各佔50%呢(構造阻塞係數0.5),在不考慮交班交接的時間,顯然8我的同時排隊加工才能在2小時完成,(加工廠只安排你的8我的)。
可是事實工廠工況是怎麼樣的呢?這個加工廠有1000人在排隊等着加工本身的產品(你安排了8我的過去加工你的產品 + 992個外人),並且,一條流水線線上工做內容切換時,前一我的和後一我的交替交接須要佔用很多時間,並且,992個外人也各自要加工本身的產品,分配給你那8我的的時間片機會就少了。那些時間都沒爲你的產品加工,都直接是劃歸到阻塞時間上去,阻塞係數變大,最佳線程數=CPU執行核心數/(1-阻塞係數), 分母變小,結果天然變大。若是你要得到更多的時間片,你就要安排更多人過去,增大佔時間片的機會。
因此你安排8我的去加工,確定2小時完成不了,可能實際用了3小時才加工完成。可是你若安排16我的過去排隊加工,可能2.5小時就能加工完成了。
如此而已。