關於最佳線程數的計算的准確理解


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)

To determine the number of threads, we need to know two things:
• The number of available cores
• The blocking coefficient of tasks

根據描述,最佳線程數量=CPU執行核心數/(1-阻塞系數);

許多程序員就立馬寫個程序測試,模擬一個阻塞系數0.5的線程,硬件配置CPU執行核心數是4,恰好2倍核心數,最佳線程數量是8,然后就開8個線程去處理。測試完成任務處理時間是316ms。以為這樣是最佳了。然后又抱着懷疑的態度再做一輪測試,特意開16個線程去一跑,發現時間只用了215ms。更少了。咦?怎么回事呢?然后得出結論:最佳線程數量並非最佳。 4倍才是最佳的。是這樣嗎?問題出在哪里了呢?

其實,如果全系統只運行你一個程序,只考慮測試代碼,阻塞系數是0.5,當然是沒錯的,但是這個公式是針對全系統而言的,需要把全系統所有程序的線程占用的timeslice都計算在內考慮。理論計算是需要考慮所有細節的,這些細節占用的時間可一點不少。

當全系統線程數量遠遠大於執行核心數,則增加了線程的上下文環境交換時間等等,還有其他線程分走了許多CPU時間片,這部分時間可不少,可是卻沒有用在你的測試計算上。為簡化理解,直接把這部分時間都划算到阻塞時間上,等於說阻塞系數變大,純工作系數變小;分母就變小了,最佳線程數量就成倍增大了。

如果還不理解,我舉個例子,用實際場景來解釋就明白了。

一個加工廠有4條加工流水線,每一個人同時只能占用一條流水線加工自己的產品,假定一個人占據一條加工流水線完全飽和工作8小時能完成自己的加工,那么拆分到4條線上顯然2小時可以加工完成,理論上。

再假定人的飽和工作時間和空閑時間各占50%呢(構造阻塞系數0.5),在不考慮交班交接的時間,顯然8個人同時排隊加工才能在2小時完成,(加工廠只安排你的8個人)。

但是事實工廠工況是怎么樣的呢?這個加工廠有1000人在排隊等着加工自己的產品(你安排了8個人過去加工你的產品 + 992個外人),而且,一條流水線線上工作內容切換時,前一個人和后一個人交替交接需要占用不少時間,而且,992個外人也各自要加工自己的產品,分配給你那8個人的時間片機會就少了。那些時間都沒為你的產品加工,都直接是划歸到阻塞時間上去,阻塞系數變大,最佳線程數=CPU執行核心數/(1-阻塞系數), 分母變小,結果自然變大。如果你要獲得更多的時間片,你就要安排更多人過去,增大占時間片的機會。

所以你安排8個人去加工,肯定2小時完成不了,可能實際用了3小時才加工完成。但是你若安排16個人過去排隊加工,可能2.5小時就能加工完成了。

如此而已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM