cpu個數、核數、線程數、Java多線程關系的理解


cpu個數、核數、線程數、Java多線程關系的理解

一 cpu個數、核數、線程數的關系

cpu個數:是指物理上,也及硬件上的核心數;

核數:是邏輯上的,簡單理解為邏輯上模擬出的核心數;

線程數:是同一時刻設備能並行執行的程序個數,線程數=cpu個數 * 核數

二 cpu線程數和Java多線程

首先明白幾個概念:

 

(1) 單個cpu線程在同一時刻只能執行單一Java程序,也就是一個線程

(2) 單個線程同時只能在單個cpu線程中執行

(3) 線程是操作系統最小的調度單位,進程是資源(比如:內存)分配的最小單位

(4)Java中的所有線程在JVM進程中,CPU調度的是進程中的線程

(5)Java多線程並不是由於cpu線程數為多個才稱為多線程,當Java線程數大於cpu線程數,操作系統使用時間片機制,采用線程調度算法,頻繁的進行線程切換。

a 那么java多進程,每個進程又多線程,cpu是如何調度的呢?

個人理解:操作系統並不是單純均勻的分配cpu執行不同的進程,因為線程是調度的最小單位,所以會根據不同進程中的線程個數進行時間分片,均勻的執行每個線程,也就是說A進程中有10個線程,而B進程中有2個進程,那么cpu分給進程的執行時間理論上應該是5:1才合理。

b cpu線程數和java線程數有直接關系嗎?

個人理解:沒有直接關系,正如上面所說,cpu采用分片機制執行線程,給每個線程划分很小的時間顆粒去執行,但是真正的項目中,線程要做很多的的操作,讀寫磁盤、數據邏輯處理、出於業務需求必要的休眠等等操作。

c 如何確定程序線程數?

個人理解:一般情況程序線程數等於cpu線程數的兩到三倍就能很好的利用cpu了,過多的程序線程數不但不會提高性能,反而還會因為線程間的頻繁切換而受影響,具體需要根據線程處理的業務考略,不斷調整線程數個數,確定當前系統最優的線程數。

 

 

 

 

 

 

      線程數是一種邏輯的概念,簡單地說,就是模擬出的CPU核心數。比如,可以通過一個CPU核心數模擬出2線程的CPU,也就是說,這個單核心的CPU被模擬成了一個類似雙核心CPU的功能。我們從任務管理器的性能標簽頁中看到的是兩個CPU。 比如Intel 賽揚G460是單核心,雙線程的CPU,Intel 酷睿i3 3220是雙核心 四線程,Intel 酷睿i7 4770K是四核心 八線程 ,Intel 酷睿i5 4570是四核心 四線程等等。
       對於一個CPU,線程數總是大於或等於核心數的。一個核心最少對應一個線程,但通過超線程技術,一個核心可以對應兩個線程,也就是說它可以同時運行兩個線程。 CPU的線程數概念僅僅只針對Intel的CPU才有用,因為它是通過Intel超線程技術來實現的,最早應用在Pentium4上。如果沒有超線程技術,一個CPU核心對應一個線程。所以,對於AMD的CPU來說,只有核心數的概念,沒有線程數的概念。


  CPU之所以要增加線程數,是源於多任務處理的需要。線程數越多,越有利於同時運行多個程序,因為線程數等同於在某個瞬間CPU能同時並行處理的任務數。 



物理cpu:實際server中插槽上的cpu的個數,物理cpu的數量,可以數不重復的physical id 有幾個

 

邏輯cpu:Linux用戶對 /proc/cpuinfo 這個文件肯定不陌生. 它是用來存儲cpu硬件信息的,信息內容分別列出了processor 0 – n 的規格。這里需要注意,如果你認為n就是真實的cpu數的話, 就大錯特錯了,一般情況,我們認為一顆cpu可以有多核,加上intel的超線程技術(HT), 可以在邏輯上再分一倍數量的cpu core出來,邏輯CPU數量=物理cpu數量 x cpu cores 這個規格值 x 2(如果支持並開啟ht),備注一下:Linux下top查看的CPU也是邏輯CPU個數

      # 總核數 = 物理CPU個數 X 每顆物理CPU的核數 
       # 總邏輯CPU數 = 物理CPU個數 X 每顆物理CPU的核數 X 超線程數

 

       # 查看物理CPU個數
       cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

 

       # 查看每個物理CPU中core的個數(即核數)
       cat /proc/cpuinfo| grep "cpu cores"| uniq

 

       # 查看邏輯CPU的個數
       cat /proc/cpuinfo| grep "processor"| wc -l

 

       #查看線程數                                                                                                                                                                                                     grep 'processor'        /proc/cpuinfo | sort -u | wc -l      注意,此處查看的線程數是總得線程數,可以理解為邏輯cpu的數量

 

 

 

 

 

 

 

CPU核數跟多線程的關系

一直以來有這樣的疑惑,單核CPU適合多線程嗎?是不是幾個核的CPU開幾個線程是最合適的?

今天就這一問題查了一些資料,現整理如下:

    要說多線程就離不開進程,進程和線程的區別在這里就不詳細說了,只將關鍵的幾點:

a)進程之間是相互獨立的,不共享內存和數據,線程之間的內存和數據是公用的,每個線程只有自己的一組CPU指令、寄存器和堆棧,對於線程來說只有CPU里的東西是自己獨享的,程序中的其他東西都是跟同一個進程里的其他線程共享的。

b)操作系統創建進程時要分配好多外部資源,所以開銷大。(這個跟操作系統有關,有人做過實驗,window創建進程的開銷大,linux創建進程的開銷就很小。)

    再來說一下CPU,在過去單CPU時代,單任務在一個時間點只能執行單一程序。之后發展到多任務階段,計算機能在同一時間點並行執行多任務或多進程。雖然並不是真正意義上的“同一時間點”,而是多個任務或進程共享一個CPU,並交由操作系統來完成多任務間對CPU的運行切換,以使得每個任務都有機會獲得一定的時間片運行。而現在多核CPU的情況下,同一時間點可以執行多個任務,具體到這個任務在CPU哪個核上運行,這個就跟操作系統和CPU本身的設計相關了。

    我們假設一個極端的情況:在一台單核計算機上只運行2個程序,一個是我們的程序A,另一個是操作系統的程序B,每個程序是一個進程。單核CPU的時候,A和B在CPU上交替運行,具體的分配方式由操作系統來判斷,我這里猜測應該跟A和B的線程數有關,因為線程是CPU級別的,如果A有5個線程,B也有5個線程,那么CPU分配給A和B的時間應該是1:1的;如果A增加到15個線程,CPU分配給A和B的時間應該是3:1的比例。所以此時如果A的線程數多,那么獲得的CPU執行次數就多,處理的速度也就快了。以上假設的前提是:①A和B的優先級相同,②A和B都是只消耗CPU資源的程序。

如果相同的情況用一個雙核的計算機來處理又會是什么結果呢?假設這個雙核的計算機和操作系統比較傻,把A進程分配到核1上,B進程分配到核2上,那不管A有幾個線程,都是用核1來處理,那么時間肯定是一樣的。不過現實中應該不會有這么傻的CPU和操作系統吧。偷笑所以趕緊還是會根據線程來進行處理,當A的線程比B多時,會占用核2來處理A的線程。

    剛才說的是只消耗CPU資源的程序,但這樣的程序在實際應用中基本上是沒有的,總會有跟資源打交道的。比如讀個文件,查個數據庫,訪問一個網絡連接等等。這個時候多線程才真正體現出優勢,在一個進程中,線程a去讀文件,線程b去查數據庫,線程c去訪問網絡,a先用一下CPU,然后去讀文件,此時CPU空閑,b就用一下,然后去查數據庫,……,相對於讀文件、查數據庫、訪問網絡來說CPU計算的時間幾乎可以忽略不計,所以多線程實際上是計算機多種資源的並行運用,跟CPU有幾個核心是沒什么關系的。

 

 

 

對於一個CPU,線程數總是大於或等於核心數的。一個核心最少對應一個線程,但通過超線程技術,一個核心可以對應兩個線程,也就是說它可以同時運行兩個線程。 
  CPU的線程數概念僅僅只針對Intel的CPU才有用,因為它是通過Intel超線程技術來實現的,最早應用在Pentium4上。如果沒有超線程技術,一個CPU核心對應一個線程。所以,對於AMD的CPU來說,只有核心數的概念,沒有線程數的概念。 
  CPU之所以要增加線程數,是源於多任務處理的需要。線程數越多,越有利於同時運行多個程序,因為線程數等同於在某個瞬間CPU能同時並行處理的任務數。 
  在Windows中,在cmd命令中輸入“wmic”,然后在出現的新窗口中輸入“cpu get *”即可查看物理CPU數、CPU核心數、線程數。其中, 
  Name:表示物理CPU數 
  NumberOfCores:表示CPU核心數 
  NumberOfLogicalProcessors:表示CPU線程數

 

 

 

 

 

 

 

 

 

 

單核多CPU與多核單CPU

一台計算機的處理器部分的架構

單核多CPU,那么每一個CPU都需要有較為獨立的電路支持,有自己的Cache,而他們之間通過板上的總線進行通信。(一致性問題)

假如在這樣的架構上,我們要跑一個多線程的程序(常見典型情況),不考慮超線程,那么每一個線程就要跑在一個獨立的CPU上,線程間的所有協作都要走總線,而共享的數據更是有可能要在好幾個Cache里同時存在。這樣的話,總線開銷相比較而言是很大的,怎么辦?那么多Cache,即使我們不心疼存儲能力的浪費,一致性怎么保證?
多核單CPU,那么我們只需要一套芯片組,一套存儲,多核之間通過芯片內部總線進行通信,共享使用內存。在這樣的架構上,如果我們跑一個多線程的程序,那么線程間通信將比上一種情形更快。

多個CPU常見於分布式系統,用於普通消費級市場的不多,多用於cluster,雲計算平台什么的。多CPU架構最大的瓶頸就是I/O,尤其是各個CPU之間的通訊,低成本的都用100M以太網做,稍微好一點的用1000M以太網,再好的就用光纖等等,但無論如何速度和通量都比不上主板的主線。所以多CPU適用於大計算量,對速度(時間)不(太)敏感的任務,比如一些工程建模,或者像SATI找外星人這種極端的,跑上幾千年都不着急的。而且多CPU架構更簡單清晰,可以用消費級產品簡單做數量堆疊,成本上有優勢。而多核單CPU則適合對通訊I/O速度要求較快的應用,(相同核數量下)成本上也高一些,好像只有在超級計算機里會用到以萬為單位的核心數,普通消費級產品也就是到16核封頂了,因為成本控制的原因。

 

 


在Windows中,在cmd命令中輸入“wmic”,然后在出現的新窗口中分別輸入“cpu get Name”,“cpu get NumberOfCores”,“cpu get NumberOfLogicalProcessors”即可查看物理CPU數、CPU核心數、線程數。
如下圖所示:

Name:表示物理CPU數 
NumberOfCores:表示CPU核心數 
NumberOfLogicalProcessors:表示CPU線程數
注釋:VM虛擬機中的CPU選擇的核心數實際是代表線程數。

輸入“cpu get *”也可

2.在cmd命令中輸入“systeminfo”,以下信息表示物理CPU有兩個

   

 

 

 

 

 

 

 

 


免責聲明!

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



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