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,而他們之間通過板上的總線進行通信。(一致性問題)
在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有兩個

