多核CPU開多少線程效率最高?

雙核的CPU是否意味著兩個線程可以同時運行,還是說一時間只能運行一個,等待其調度。

那在多核CPU的計算機上,一個程序應該開多少線程效率最高呢


這個問題相當複雜。多核 CPU 的每個核都有獨立的運算器,但是其它部件(比如 on-die cache)是獨立的還是共享,依具體的 CPU 而不同。有些 CPU 每個核有兩個運算器,所以可以實現超線程技術(用一個核模擬兩個虛擬核),而超線程技術的效率又取決於每個核的部件冗餘程度。另外,在所有 SMP 構架中,所有核共享內存匯流排。

開多少線程效率最高,和線程的任務利用何種部件,以及這些部件的獨立/共享狀態相關。對於重度讀寫拷貝內存的線程,不管 CPU 有多少核,開兩三個線程就可能效率下降。對於僅僅使用運算器的任務,則要把超線程的邏輯核都用滿才算高效率。而中間的狀態可以以此類推。


謝邀。

如果你確實想深入了解這個話題,建議深度閱讀一下相關材料。比如WIKI上的CPU的架構,多線程,多核等等。一定要準確了解相關概念。你問了一個很大的問題,也是沒有確切數字答案的問題。多線程設計是並行程序設計的一個重要構成。

舉個簡單的例子。體育場內的長跑比賽中,參賽選手在各自的賽道起跑,但跑起來了以後都會去爭搶內道。內道作為一種稀缺資源,可以給跑在上面的選手帶來種種優勢,但如果爭搶的人太多,就會出現碰撞和摩擦,對所有人都有影響。同時,如果我們希望所有運動員跑過的總里程越長越好,那似乎運動員應該儘可能的多,可人越多,帶來的摩擦和爭搶也會越多。誇張一點的說,如果5個人搶內道還行,那麼100個人搶內道就肯定一片混亂了,最後誰也跑步好,或者不得不前後挨著排成一列,搞不好還有人要受傷。每一個線程就相當於一個運動員,而處理器就是一個非常複雜的體育場。

能夠開多少線程,首先取決於程序對多線程的支持。由於演算法的問題,有的程序只能支持有限的線程數或者2的n次方個線程,多餘這個數量就會出現錯誤。希望更多的線程,並行性更好的線程,往往需要在演算法和實現上進行改性。

其次,每個CPU都有不同的結構。比如是否支持超線程,L2 Cache是否共享,NUMA region是怎樣的等等。在一些特殊的x86處理器上,這樣的區別還會要求程序員專門設計程序。比如Xeon Phi中每一個核都有兩個pipeline,有一套專門的512bit的向量處理單元,執行自己的向量指令集,這就需要程序的實現更加有針對性。

在同樣的架構上,每一個線程的workload是否balance,需要什麼樣的資源,對memory的讀寫有沒有衝突,critical region多不多,原子操作多不多都會影響到他們之前是否能夠很好的並行。一般而言,線程間的衝突何互斥越少越好。

此外,多線程不僅局限於CPU。除了上面提到的Xeon Phi,還有GPU、APU等,涉及到的編程語言也有OpenCL、CUDA、OpenACC、OpenMP等等等等。這裡面牽扯到線程數量的因素非常多。


不邀自答。

1. 多核心意味著有兩個或兩個以上的獨立實體中央處理單元,兩個單元可以各自獨立地運行不同指令,是真正的並行。

2. 但凡寫過程序就應該知道任務背景不同,多線程的效果也不同,如果有IO、網路的等待,兩個核心你開兩個線程,那線程一旦阻塞了,這個核心就閑置了。

3. 超線程,就是如果兩個線程在同一時間的指令使用的流水線單元(像分支預測器)不一樣, 則一個核可以同時處理。但理想情況總是較少的,所以比起真正的兩個核心還是差得遠。萬一發生資源互搶的情形時,整體性能反而會下降。

4. IOCP示例往往開CPU數量*2+2或者CPU數量*2個線程,可能有像第2點所說的避免閑置的作用,不過如果線程是計算密集的,開得線程多了,反而會把資源浪費在上下文切換上。

總之:

在單核心下,為了實現偽多任務,要把一堆時間片分給不同任務,所以多線程除了有IO、網路等的等待,在實質很難提高效率;

在多核心下,多線程一般都可以提高效率的,但具體設計多少個線程還是得看具體情況;

至於超線程,目前效果並不好,建議編寫程序時參考Intel系統編程指南,還有這篇文章:超線程技術適合什麼樣的程序?,據說在網路伺服器上效果還是有的。

現在搞非同步、協程的比較多,題主也不妨看下。


說到效率,那假設前提計算資源相比程序是瓶頸一方,如果線程之間都並行,相互之間沒有關係,當然是跟CPU等數量最好(超線程不談),什麼Cache不中之類根本不需要考慮,否則硬體體系結構肯定就不過關。那下一步就是操作系統調度的問題,成熟的操作系統在應對這種最簡單的情形也肯定不會讓CPU閑在那裡。

如果超過了CPU數量,顯然需要多餘的調度代碼來執行,而總的計算能力不會增加,那麼比不過相等的情形。

複雜一點是線程之間有同步/競爭關係,那麼考慮到cache不中的等情形,就很難說能提高多少,但絕大多數需要足夠運算能力的情形下,也基本可以認為等同是最佳的。除非故意把代碼分割成粒度極小的執行單元,但想到調度也可能早已成為性能瓶頸了,這種故意劣化cpu性能的代碼也很難在真實世界中上演。

實際上,在目前主流程序設計語言中,因為缺少較好的協程同步機制,而對於非同步代碼大多數情況有覺得用多線程寫起來更加容易,即要不很難做到任務並行劃分,要不就開大量線程,很少人會想到要做到恰好等同cpu數量。同時極度消耗計算資源的時候也是很少的,所以大多數情形下這也不是一個問題,搞並行高性能計算才需要關心一下。


推薦閱讀:

cpu的線程和操作系統的線程有什麼關係?
Linux系統中 進程 、線程 、時間片的關係?
如何實現一個安全的thread.stop的api?
線程崩潰是否會造成進程崩潰?

TAG:中央處理器CPU | 編程 | 線程 |