從1980 年到1995 年:計(jì)算機(jī)體系結(jié)構(gòu)理論的熱潮
怎樣才能制造出性能更好的計(jì)算機(jī)?在此之前計(jì)算機(jī)的發(fā)展大多依靠架構(gòu)師的經(jīng)驗(yàn)和直覺,一旦架構(gòu)師直覺失誤或者技術(shù)無(wú)法支撐架構(gòu)師的想法,很可能一代計(jì)算機(jī)的研究就荒廢掉,一家公司也可能因此倒閉。但從1980 年開始,計(jì)算機(jī)開始走上一條理論指導(dǎo)實(shí)踐的道路,如何平穩(wěn)的提升計(jì)算機(jī)的性能,成了學(xué)術(shù)界的研究熱點(diǎn)。這方面的技術(shù)主要分為三大類,指令級(jí)并行、數(shù)據(jù)級(jí)并行和線程級(jí)并行。首當(dāng)其沖的,是對(duì)指令集的調(diào)整。
精簡(jiǎn)指令集計(jì)算機(jī)
1980 年P(guān)atterson 提出了要設(shè)計(jì)精簡(jiǎn)指令集計(jì)算機(jī)RISC[29]。當(dāng)時(shí)的微處理器設(shè)計(jì)面臨許多困難,包括CISC 芯片設(shè)計(jì)復(fù)雜度增加,復(fù)雜指令導(dǎo)致編譯器選擇指令困難。而從實(shí)際指令使用情況來(lái)看,IBM 360 上10 條指令就可以滿足程序80% 的需要,要覆蓋99% 的需要也不過(guò)需要30 條指令。RISC 具有許多優(yōu)點(diǎn),例如方便VLIW 設(shè)計(jì)、降低設(shè)計(jì)成本、更好的利用芯片面積和更高的指令速度。Patterson 還舉例了在IBM、貝爾實(shí)驗(yàn)室和UCB 的相關(guān)研究工作,推動(dòng)RISC 的發(fā)展。
盡管遇到了一些反對(duì)的聲音[30],但后來(lái)的歷史表明RISC 的道路是正確的。后來(lái)的計(jì)算機(jī)要么是基于精簡(jiǎn)指令集的,例如MIPS、ARM、RISC-V,要么前端仍然是復(fù)雜指令,但是通過(guò)譯碼轉(zhuǎn)換成精簡(jiǎn)指令集再執(zhí)行,例如Intel、AMD 和IBM。指令集是計(jì)算機(jī)硬件和軟件的接口,新的指令集得到認(rèn)可,接下來(lái)的任務(wù)就是如何高效的利用流水線。為此人們開始深入挖掘微處理器指令級(jí)并行的能力。
超長(zhǎng)指令字與超標(biāo)量
超長(zhǎng)指令字VLIW 技術(shù)和超標(biāo)量Superscalar 技術(shù)在思想上非常類似,都試圖在一個(gè)周期里發(fā)射多條指令,提升微處理器的并行度。差別在于,超長(zhǎng)指令字需要編譯器分析指令間的依賴關(guān)系,并進(jìn)行打包,以提示微處理器并行發(fā)射;而超標(biāo)量則完全是硬件執(zhí)行的動(dòng)作,由硬件完成依賴分析和發(fā)射。目前大多數(shù)的微處理器都采用超標(biāo)量的技術(shù)以減輕編譯器的負(fù)擔(dān),而且可以在更大的指令窗口中進(jìn)行調(diào)度,超長(zhǎng)指令字的概念提的比較少了。在接下來(lái)要介紹微處理器中,大多數(shù)都采用了超標(biāo)量技術(shù),每周期可以發(fā)射多條指令,典型的例子包括MIPS R10000[31]。IBM 的Power 系列有些特別,采用對(duì)指令打包處理的方法提供并行性[32]。
分支預(yù)測(cè)器
分支預(yù)測(cè)器是至今仍是微處理器研究的重要部分,性能預(yù)測(cè)器每提升一個(gè)百分點(diǎn)都能明顯提高微處理器的性能,絕大多數(shù)商用微處理器的分支預(yù)測(cè)器設(shè)計(jì)都是不公開的。1993 年的一篇研究報(bào)告[33] 曾經(jīng)將分支預(yù)測(cè)器的性能在當(dāng)時(shí)的負(fù)載條件下提高到98%,因此被許多微處理器借鑒[32, 34, 35]。我們來(lái)看他是怎么做的。
聯(lián)合分支預(yù)測(cè)器使用一個(gè)局部預(yù)測(cè)器和一個(gè)全局預(yù)測(cè)器同時(shí)預(yù)測(cè)分支方向,并使用第三個(gè)預(yù)測(cè)器預(yù)測(cè)使用哪一個(gè)結(jié)果。局部預(yù)測(cè)器使用部分PC 索引,每個(gè)表項(xiàng)對(duì)應(yīng)一個(gè)兩位的計(jì)數(shù)器,計(jì)數(shù)器的高位作為預(yù)測(cè)方向,并根據(jù)預(yù)測(cè)的正確與否做出相應(yīng)的調(diào)整。全局預(yù)測(cè)器使用PC 和到達(dá)該分支的程序路徑上其他分支的跳轉(zhuǎn)方向作為索引,可以使用拼接或者異或的方式整合信息。每個(gè)條目的結(jié)構(gòu)和局部預(yù)測(cè)器類似。選擇預(yù)測(cè)器同樣使用PC 索引,每個(gè)表項(xiàng)也是一個(gè)兩位計(jì)數(shù)器,其結(jié)果表示選用全局預(yù)測(cè)器的結(jié)果還是局部預(yù)測(cè)器的結(jié)果。
分支預(yù)測(cè)器相關(guān)工作近年來(lái)仍有學(xué)者研究,在新的工作負(fù)載和新的技術(shù)手段之下繼續(xù)提升分支預(yù)測(cè)的效率。同時(shí),也有人研究如何預(yù)測(cè)分支跳轉(zhuǎn)的地址,以及和程序調(diào)用有關(guān)的分支預(yù)測(cè)。除了分支預(yù)測(cè)正確率之外,分支預(yù)測(cè)失敗時(shí)的懲罰也是很重要的參數(shù)。
指令級(jí)并行的極限
就在人們興致勃勃的想盡各種方法挖掘指令級(jí)并行的時(shí)候,一篇文章的出現(xiàn)打破了人們的美夢(mèng):指令級(jí)并行是有極限的[36]。假設(shè)在完美的寄存器重命名、完美的分支預(yù)測(cè)器、完美的別名分析、超大的指令窗口、運(yùn)算部件全流水的情況下,程序本身的并行度有多少?模擬的結(jié)果表明并行度(按照文中的定義)大概在20到60 左右,一些輕微的不完美就會(huì)使得該值將至10 左右。這樣的結(jié)果大致指明了指令級(jí)并行,或者叫循環(huán)級(jí)并行的極限。大概十年之后,隨著集成晶體管的數(shù)量進(jìn)一步增加,微處理器的設(shè)計(jì)者們終于撞到了指令級(jí)并行的極限上,不得不轉(zhuǎn)而尋找其他方法。
Vector、SIMD 與GPU
想要突破指令級(jí)并行的極限,一種方法就是通過(guò)數(shù)據(jù)級(jí)并行。早期的超級(jí)計(jì)算機(jī),例如CDC 6600、Cary-1、Illiac IV,都有向量執(zhí)行的功能,摩爾定律的發(fā)展使得在微處理器中添加向量部件成為可能。另一方面,多媒體應(yīng)用的興起也迫切需要SIMD 的支持,這類負(fù)載中最常見的操作就是對(duì)一組數(shù)據(jù)采取同樣的操作行為。Intel 在其后續(xù)微處理器[37–39] 當(dāng)中逐步增加了向量指令的支持,增加了諸如MMX、SSE、AVX 指令集供程序員使用。同時(shí)運(yùn)算部件增加向量運(yùn)算單元,支持SIMD 功能,并逐步提升向量寬度。將數(shù)據(jù)級(jí)并行做到極致的當(dāng)屬NVIDA 公司的GPU,通過(guò)專用硬件為圖形工作者、游戲愛好者、機(jī)器學(xué)習(xí)研究者提供向量加速和強(qiáng)大的浮點(diǎn)計(jì)算能力。
多線程技術(shù)
還有沒(méi)有其他方法提高并行度呢?有的,答案是多線程技術(shù)。一直以來(lái),一個(gè)微處理器上同一時(shí)間只能運(yùn)行一個(gè)線程,通過(guò)操作系統(tǒng)的幫助完成線程間切換達(dá)到多線程同時(shí)運(yùn)行的假象。如果每個(gè)微處理器上可以運(yùn)行多個(gè)線程,那么當(dāng)某個(gè)線程因?yàn)榱魉€阻塞而等待的時(shí)候,執(zhí)行另一個(gè)線程的指令是不是就能填補(bǔ)原本被浪費(fèi)的時(shí)鐘周期了呢?本著這樣的想法,主流的微處理器廠商紛紛推出了超線程技術(shù)[32, 38, 40]。尤其是在服務(wù)器這樣需要同時(shí)對(duì)多個(gè)鏈接進(jìn)行服務(wù)的場(chǎng)景,對(duì)多線程技術(shù)需求更大,因此Power 系列每個(gè)核心可以支持4 個(gè)線程同時(shí)運(yùn)行[41]。