CPU有很多硬件提升手段漓藕,其中較為常見的是超標(biāo)量(superscalar)、流水線(pipelining)挟裂、超線程(Hyper-Threading)享钞、多核(multi-core)、SIMD等诀蓉,通常較難理解栗竖,本文以洗衣服為例嘗試通俗理解這些概念.
假如把一個線程任務(wù)模擬成洗衣機(jī)器操作,那一個線程包含多個指令(處理上衣渠啤、處理褲子狐肢、處理襪子.....),一個指令又包含多個周期(取衣服、洗衣服沥曹、晾衣服......)份名;CPU 就是那洗衣工廠,工廠里有取衣機(jī)器 A妓美、洗衣機(jī)器 B僵腺、晾衣機(jī)器 C 、燙衣機(jī)器 D壶栋、衣服放回機(jī)器 E辰如,一開始流程如下:
1.機(jī)器A取上衣--機(jī)器B洗上衣--機(jī)器C晾上衣--機(jī)器D燙上衣--機(jī)器E放回上衣
2.機(jī)器A取褲子--機(jī)器B洗褲子--機(jī)器C晾褲子--機(jī)器D燙褲子--機(jī)器E放回褲子
3.機(jī)器A取襪子--機(jī)器B洗襪子--機(jī)器C晾襪子--機(jī)器D燙襪子--機(jī)器E放回襪子
4.機(jī)器A取鞋子--機(jī)器B洗鞋子--機(jī)器C晾鞋子--機(jī)器D燙鞋子--機(jī)器E放回鞋子
5...
最開始 CPU 就是順序執(zhí)行如上1-2-3-.....步驟的,現(xiàn)在有好幾筐(衣服贵试、褲子琉兜、鞋子......)要洗,如何提升速度毙玻?
超標(biāo)量(superscalar)
最開始樸素想法就是工廠內(nèi)多買機(jī)器豌蟋,譬如取上衣機(jī)器買 2 臺,洗衣機(jī)器買 2 臺..........
洗衣工廠就變成
1.機(jī)器A1取上衣--機(jī)器B1洗上衣--機(jī)器C1晾上衣--機(jī)器D1燙上衣--機(jī)器E1放回上衣
機(jī)器A2取褲子--機(jī)器B2洗褲子--機(jī)器C2晾褲子--機(jī)器D2燙褲子--機(jī)器E2放回褲子
2.機(jī)器A1取襪子--機(jī)器B1洗襪子--機(jī)器C1晾襪子--機(jī)器D1燙襪子--機(jī)器E1放回襪子
機(jī)器A2取鞋子--機(jī)器B2洗鞋子--機(jī)器C2晾鞋子--機(jī)器D2燙鞋子--機(jī)器E2放回鞋子
3.....
這樣時間就能減半了
流水線(pipelining)
仔細(xì)看從取衣
到放回
一個流程里雖然每個機(jī)器都用到了淆珊,但任何一個時刻都只有一個機(jī)器在工作.
譬如:機(jī)器 A1/A2取完衣服后就空閑者一直到E1/E2放回衣服才繼續(xù)工作夺饲,大部分時候都空閑著。
流水線就是不讓任何一個機(jī)器空閑施符,沒必要一個指令周期走完往声,可以繼續(xù)執(zhí)行其他指令。
T1 時刻:機(jī)器A1取上衣
T2 時刻:機(jī)器B1洗上衣+機(jī)器A1取褲子
T3 時刻:機(jī)器C1晾上衣+機(jī)器B1洗褲子+機(jī)器 A1 取襪子
T4 時刻:機(jī)器D1燙上衣+機(jī)器C1晾褲子+機(jī)器 B1 洗襪子+機(jī)器 A1 取鞋子
........
縱向看仍然是一個指令的完整周期(取衣服戳吝、洗衣服浩销、晾衣服.....), 橫向看會發(fā)現(xiàn) A1 一直在工作被利用起來了,只要一直運行時間會發(fā)現(xiàn) A1 ~ E1 各個機(jī)器都會被利用起來持續(xù)工作听哭。
超線程(Hyper-Threading)
超標(biāo)量(superscalar)和流水線(pipelining)都是線程里的優(yōu)化方案慢洋,能讓單線程程序跑的更快塘雳,而超線程(Hyper-Threading)就是不同線程間的優(yōu)化方案了。
因為有的線程涉及和外部的數(shù)據(jù)交換普筹,譬如需要等數(shù)據(jù)從內(nèi)存乃至更慢的網(wǎng)絡(luò)败明、磁盤裝載到 L1、L2 chache太防,這時候可以讓 CPU處理另一個線程妻顶。
繼續(xù)類比就類似于洗衣工廠發(fā)現(xiàn)某籮筐 A 里的衣服較臟需要等洗衣液送過來才能繼續(xù)洗,那可以保存籮筐A 的進(jìn)度轉(zhuǎn)而洗那些較干凈無需等外部的某籮筐B(yǎng)里的衣服蜒车,等外部的洗衣液送過來后再處理籮筐A 里的衣服讳嘱。
所以越是 IO 密集型應(yīng)用,超線程效果就越大酿愧,譬如DBA 一般建議MySQL 的thread_running
參數(shù)設(shè)置為 cpu 核數(shù)*2
,這就是把超線程當(dāng)成真正的核來用了沥潭。
超線程對 CPU 密集型應(yīng)用就無用了,CPU 核數(shù)是多少就只能開多少任務(wù)嬉挡。
日常應(yīng)用來說超線程能提升 30%的吞吐量, 而這 30%的提升只是增加了 5%的額外電路钝鸽,看起來性價比很高;但開啟多線程會犧牲單線程的性能棘伴,而且現(xiàn)在大部人日常應(yīng)用根本用不滿CPU的那么多核和線程寞埠,所有有些 CPU(如MacBook的 M 系列 CPU)就沒有超線程技術(shù)。
多核(multi-core)
多核(multi-core)很容易理解了焊夸,還是以洗衣服為例幾個核就是額外再建幾個洗衣工廠,當(dāng)然成本也是跟著翻幾倍蓝角。
SIMD
上面的例子都是假設(shè)機(jī)器一次只能處理一件任務(wù)阱穗,那能不能改造下機(jī)器(譬如增加機(jī)械臂)讓機(jī)器 A 一次取 10 件而不是 1 件衣服,讓機(jī)器 B 一次洗 10 個鞋子而不是 1 個使鹅?
SIMD就是類似思路揪阶,事實上這就是 SIMD 被叫做單指令流多數(shù)據(jù)流的原因,一次處理大量類似的數(shù)據(jù)患朱,譬如多媒體數(shù)據(jù)鲁僚、數(shù)據(jù)分析/AI領(lǐng)域 的矩陣數(shù)據(jù)。
譬如Python的Numpy庫就是用了SIMD指令集 AVX 系列(AVX裁厅、AVX2乃至AVX512)來處理數(shù)據(jù)冰沙,所以哪怕沒用GPU速度也很快。