探索底層的意義話說人們在1870年左右開始應(yīng)用黃色火藥,在1900年左右開始大量普及電動地鐵,并建成了埃菲爾鐵塔(1898)等偉大工程,但是軍事技術(shù)的發(fā)展、革新最多的僅是二戰(zhàn)前后的1936到1945的這幾年時間,現(xiàn)在的軍事技術(shù)也大都僅是對二戰(zhàn)時的軍事技術(shù)體系的深化,如自動步槍,噴氣引擎,潛艇,坦克和反坦克等等。所以我們認(rèn)為,高強(qiáng)度的行業(yè)競爭,帶來其領(lǐng)域技術(shù)的深入發(fā)展,而因其深入的發(fā)展,其中的許多設(shè)計理念和產(chǎn)出,往往惠及了很多的民用領(lǐng)域,如復(fù)雜的渦輪增壓技術(shù)是二戰(zhàn)戰(zhàn)斗機(jī)的標(biāo)配,現(xiàn)在也經(jīng)過簡化,惠及到民用汽車領(lǐng)域。 而現(xiàn)在信息技術(shù)領(lǐng)域中白熱化的競爭莫過于Intel和AMD之間的藍(lán)紅之爭,其競爭讓CPU的設(shè)計和架構(gòu)經(jīng)過千錘百煉,是一個現(xiàn)代人類設(shè)計和實踐的結(jié)晶。因此我們探究一下CPU底層的實現(xiàn),其中的思路和理念,特別是現(xiàn)在多核心CPU的設(shè)計,也會對我們的高性能系統(tǒng),以及分布式系統(tǒng)的設(shè)計和使用有很多借鑒和幫助。 另外其實人們也發(fā)現(xiàn)往往一些帶有分形的東西,其不僅廣泛存在,而且也代表著很多我們未知的合理結(jié)構(gòu),如人們所說的黃金分割,宇宙及黑洞等,其也都和分形有關(guān)聯(lián),分形可以簡單理解為不斷深入的底層構(gòu)成,和其上層構(gòu)成有結(jié)構(gòu)上的相似。因此我們探究底層的設(shè)計,也對我們上層系統(tǒng)的設(shè)計有一定的參考和指導(dǎo)作用。 CPU的緩存結(jié)構(gòu)簡介如下圖所示是Intel的Skylake的CPU架構(gòu),我們可以看到緩存被分為L1、L2、L3這3層,CPU在運行中首先使用自己的寄存器,然后使用速度更快的L1緩存,其中:L1D緩存數(shù)據(jù);L1I緩存指令;L1緩存和次快的L2同步數(shù)據(jù);L2緩存和L3緩存同步數(shù)據(jù)(這里L(fēng)2和L3按照內(nèi)核數(shù)量做了等分,分給各個內(nèi)核使用),我們可以簡單地認(rèn)為L3和內(nèi)存同步數(shù)據(jù)。 Intel的PPT 中Skylake的緩存示意圖的截圖 為什么會有這么多級的緩存呢?因為每級緩存的速度差異很大,越快的緩存容量越小,因此CPU把緩存分成多級,每一級作為上一級的緩存。(其實在多核的情況下訪問緩存會有一些同步問題,我們在下文討論) CPU的緩存性能參考而我們可以認(rèn)為目前CPU的緩存性能差異如表所示(參考了卡耐基梅隆大學(xué)在2014年的教案等)。 緩存性能表 在上表中要注意以下內(nèi)容: 1. L1、L2、L3的最小讀寫單位是64bit(8字節(jié))。 2. L2的周期已包含L1(miss)的周期,L3的周期已包含L2(miss)的周期。 3. 內(nèi)存訪問應(yīng)該還有TLB(虛擬地址頁表緩存)的miss的情況,會增加少量周期。 4. 其實CPU的寄存器的整體大小為2KB左右,在64位下除了RAX、RBX、RCX、RDX、RSI、RDI、RSP、RBP、R8-R15這16個通用寄存器,如Intel還大概有:MMX:80bit X 8,ZMM(YMM,XMM):512bit X 32等寄存器,還有控制:64bit X 16,調(diào)試:64bit X 16,以及其他零散分類下及系統(tǒng)自用的若干。 因為這些緩存和內(nèi)存在性能上的差異,所以對CPU的密集運算則是越少訪問內(nèi)存越好,比如在發(fā)生一次CAS操作時,如果這個內(nèi)存訪問能命中L2緩存,則還是比較高效的;但是如果L2 miss 連同 L3 miss ,則會變成一次讀內(nèi)存的重操作,影響并發(fā)的性能(約100ns的耗時),同理,對于正常的鎖的操作,緩存miss時會耗時較多(約200ns的耗時)。 當(dāng)前CPU的架構(gòu)圖下面是Intel的Skylake 的架構(gòu)圖,與Sandy Bridge 的架構(gòu)圖,和AMD的ZEN 的架構(gòu)圖。 Intel的Skylake的架構(gòu)圖 Intel的Sandy Bridge 的架構(gòu)圖 AMD的ZEN 的架構(gòu)圖 Intel和AMD的CPU的架構(gòu)圖雖然看著差異挺大,但它們的大結(jié)構(gòu)其實是一樣的,大概都分為3個模塊。 1. 前端執(zhí)行(front end):對應(yīng)Intel圖的上面及對應(yīng)AMD圖上面;這個是L1指令cache處理指令解碼(DECODE),分支預(yù)測,執(zhí)行隊列,調(diào)度器,等這些指令功能。 2. 計算:對應(yīng)INTEL圖的左下及對應(yīng)AMD圖的中間;這個就是整數(shù)計算單元和浮點計算單元。 3. 緩存/內(nèi)存:對應(yīng)INTEL圖的右下及對應(yīng)AMD圖的下面;這個就是內(nèi)存控制器(內(nèi)存讀寫控制器及隊列,以及TLB(內(nèi)存頁表的虛擬地址轉(zhuǎn)換緩存))及L1數(shù)據(jù)緩存和L2緩存。 從這些圖上我們可以看出,L1命令緩存AMD的Zen是64KB,而Intel是32KB;L2緩存AMD的Zen是512KB,Intel是256KB,這個和CPU型號也有關(guān)系,但還是說明同一代下AMD的CPU在一些配置上更優(yōu)一些。 這里也說下,網(wǎng)上流傳說,在AMD的Zen之前Intel的CPU的強(qiáng)大的浮點功能(以及除法器),是Intel在跑分上勝利的其中一個重要因素,AMD認(rèn)為都有顯卡了,顯卡浮點計算的能力非常強(qiáng)大,因此CPU不需要太強(qiáng)的浮點功能了……。 再有我們在看AMD的PPT時會發(fā)現(xiàn),除了L1數(shù)據(jù)緩存到寄存器堆(register file)還有個AGU到load/store queues模塊的箭頭,這里可能感覺比較奇怪,其實這個AGU的組件AMD和Intel都有,Intel的沒有畫出(之前的架構(gòu)PPT里有,現(xiàn)在應(yīng)該屬于Load Store Data這,但沒有畫出),這個全稱是Address Generation Unit,用來加速計算實際的物理地址,以及計算數(shù)組中的地址等。(另外,其實大家知道應(yīng)用程序中的內(nèi)存地址對CPU和操作系統(tǒng)來講都是比較麻煩的虛擬地址)。下圖是AMD的緩存/內(nèi)存單元單元的一個展開圖(圖中L1數(shù)據(jù)緩存上的To Ex是到整數(shù)計算單元,To Fp是到浮點計算單元)。如圖 AMD的緩存/內(nèi)存部分的展開圖 CPU緩存的使用上面介紹了CPU整體的架構(gòu)圖,以及緩存在CPU架構(gòu)圖中的位置,這里先介紹下CPU在單核環(huán)境下的多級緩存的架構(gòu)。 現(xiàn)在CPU都流行多核芯的架構(gòu),而我們先看其中的一個核心對緩存操作的流程,我們可以整體認(rèn)為:當(dāng)核心(Core)訪問(讀或?qū)懀㎜1緩存時沒有命中(miss)則訪問L2緩存和L3緩存,在L3緩存也沒有命中時才操作內(nèi)存。多級緩存在獨占(exclusive)模式下,L1緩存中通過LRU策略逐出的數(shù)據(jù)會到L2,在L2中逐出的會到L3,在L3中逐出的有寫入/修改的數(shù)據(jù)則同步到內(nèi)存。 緩存的操作的最小單元我們可以叫緩存單元,英文是cache line,每個緩存單元緩存64bit(8Byte)的數(shù)據(jù),訪問緩存時通過內(nèi)存單元的物理地址。另外我們??吹?WAY,16WAY這種來描述緩存,其實緩存的在使用時是個類似二維數(shù)組的形式,這里的列就是WAY,如8WAY,就是8列。訪問時通過物理地址的高位和中位從列(WAY)和行(SET)中命中一個緩存單元(cache line,也可以翻譯成緩存行),可參考下圖示意。 AMD文檔中的緩存操作示意 緩存單元因其一次必須操作連續(xù)的8Byte的數(shù)據(jù),但是我們不希望類似下面這樣的情況,如兩個相鄰的整型(4Byte)數(shù)據(jù)會同時被多個CPU核心進(jìn)行頻繁修改,而其都在一個緩存單元內(nèi),其每次修改都會觸發(fā)我們后面講的核心的緩存到內(nèi)存的同步問題。 我們先看看具體讀寫命中和未命中的情況: 1. 緩存沒有命中的情況: a). 對于單核心的讀,讀操作會先檢查緩存,在緩存中沒有數(shù)據(jù)時會載入數(shù)據(jù)到緩存(cache line fill)中。 b). 對于單核心的寫,其同讀操作,會先檢查緩存,在緩存中沒有數(shù)據(jù)時會載入數(shù)據(jù)到緩存中,然后執(zhí)行寫操作,這里寫操作只是簡單的寫了載入過來的緩存,并不同步到內(nèi)存(這里需要注意,按照Intel的開發(fā)文檔,老的Pentium默認(rèn)的情況是在緩存miss后寫操作直接寫內(nèi)存,而不是載入數(shù)據(jù)到緩存后寫緩存)。 2. 緩存命中的情況: a). 如果讀命中(cache hit),則直接使用數(shù)據(jù); b). 如果這里是寫操命(write hit)時則也是直接操作緩存,而不主動同步到內(nèi)存。 我們也看看CPU的緩存的使用流程: 1. CPU的前端解析L1命令緩存中的指令進(jìn)行預(yù)測和亂序執(zhí)行等 2. 通過這些指令,計算單元具體處理從L1數(shù)據(jù)緩存到寄存器中的數(shù)據(jù)的計算 3. 將計算的結(jié)果更新到L1數(shù)據(jù)緩存,若要同步緩存中的數(shù)據(jù)到內(nèi)存,則通過硬件實現(xiàn)的寫緩存邏輯(write buffers)可靠地異步刷新數(shù)據(jù)到系統(tǒng)總線及內(nèi)存(可理解為通過一個消息隊列寫)。 這里可以看參考下圖所示。 緩存相關(guān)流程,取自AMD技術(shù)文檔 這里則是整個單核心的的流程,我們注意到,CPU通過緩存提高性能的一個關(guān)鍵要點是在寫的情況下只寫緩存,不同步緩存數(shù)據(jù)到內(nèi)存。 推薦一起學(xué)習(xí)《分布式服務(wù)架構(gòu):原理、設(shè)計與實戰(zhàn)》一書,它是一本不可多得的理論與實踐相結(jié)合的架構(gòu)秘籍,是作者多年工作經(jīng)驗積累的結(jié)晶。京東購買請掃描下方二維碼。 如果你想成為優(yōu)秀的架構(gòu)師 在【云時代架構(gòu)】精品群免費進(jìn)! 我在【云時代架構(gòu)】技術(shù)社區(qū),你在哪里? 還等什么,趕快加入【云時代架構(gòu)】技術(shù)社區(qū)! 請猛掃下面二維碼。 云時代架構(gòu)
|
|