第十三章 RISC精简指令计算机
教材參考計(jì)算機(jī)組織與結(jié)構(gòu)——性能設(shè)計(jì)(第九版)第14章
這一章我們來(lái)講一講一種很著名的計(jì)算機(jī)架構(gòu)——RISC(另一種與其相對(duì)的叫CISC)。那么問(wèn)題來(lái)了,什么是RISC?
RISC是Reduced Instruction Set Computer,即精簡(jiǎn)指令集計(jì)算機(jī)的簡(jiǎn)稱。而與其相對(duì)的則是復(fù)雜指令集計(jì)算機(jī),這里我們不作討論。
RISC之所以叫精簡(jiǎn)指令集計(jì)算機(jī),就是因?yàn)槠渲噶畹臄?shù)目相對(duì)較少,我們先來(lái)看看它有哪些特征:
-
數(shù)量眾多的通用寄存器,可能有數(shù)十個(gè)至上百個(gè),使用特殊的編譯技術(shù)來(lái)優(yōu)化寄存器的使用。
-
指令數(shù)量少(從名字也可以看出來(lái)吧),格式固定,長(zhǎng)度也是固定的。
-
專注于優(yōu)化指令流水線。
RISC和CISC的對(duì)比圖如下:
13.1 指令執(zhí)行特點(diǎn)
在講RISC的具體特點(diǎn)之前,我們來(lái)看一看為什么會(huì)出現(xiàn)RISC。
其實(shí),在RISC出現(xiàn)之前,設(shè)計(jì)者們偏向于CISC,隨著硬件工藝的逐漸成熟,硬件的價(jià)格逐漸下降,相對(duì)而言提高的則是軟件的價(jià)格,同時(shí),高級(jí)語(yǔ)言(High Level Language)也在不斷發(fā)展,不斷變得復(fù)雜。
那么人們就想著,不如讓指令集變得更加多、更加復(fù)雜,用更加復(fù)雜的硬件實(shí)現(xiàn)來(lái)滿足高級(jí)語(yǔ)言的需要。于是,CISC就旨在簡(jiǎn)化編譯器的實(shí)現(xiàn),用更加復(fù)雜的指令集來(lái)支持高級(jí)語(yǔ)言。
但是,之后的人做了一些實(shí)驗(yàn),讓高級(jí)語(yǔ)言的程序跑起來(lái),觀察高級(jí)語(yǔ)言的語(yǔ)句在程序中執(zhí)行的次數(shù),并乘以對(duì)應(yīng)的機(jī)器指令的條數(shù),得到了如下的結(jié)果:
可以看到出現(xiàn)次數(shù)最多的是賦值,即變量的分配問(wèn)題,而最耗時(shí)的是過(guò)程調(diào)用,同時(shí)也要注意分支和循環(huán)??偨Y(jié)而言,最應(yīng)該受到關(guān)注的是關(guān)于操作、操作數(shù)和過(guò)程調(diào)用的問(wèn)題。
對(duì)于操作數(shù)而言,研究發(fā)現(xiàn),多數(shù)的變量引用是對(duì)局部的標(biāo)量;而關(guān)于過(guò)程調(diào)用的研究中發(fā)現(xiàn),過(guò)程調(diào)用需要的參數(shù)并不多,98%的過(guò)程調(diào)用都只需要6個(gè)以內(nèi)的參數(shù),而且過(guò)程調(diào)用的深度并不深。
這些有關(guān)的研究便給了設(shè)計(jì)者一些啟發(fā):
-
由于操作數(shù)大多都是局部變量,于是考慮用更多的寄存器。
-
由于分支、循環(huán)、過(guò)程調(diào)用較多,要更加小心地設(shè)計(jì)流水線。
于是便產(chǎn)生了RISC這一架構(gòu)。
13.2 大寄存器組
為什么要用寄存器組呢,這是因?yàn)榧拇嫫魇亲羁斓囊环N內(nèi)部存儲(chǔ),比cache和內(nèi)存都要快,而且由于寄存器組中的寄存器數(shù)量不多,因此尋址非常快。
但是由于存儲(chǔ)空間不大,那么就要用一些策略來(lái)決定哪些最常用的操作數(shù)放在寄存器中了。有硬件和軟件兩種方案來(lái)解決存儲(chǔ)空間不足的問(wèn)題。
-
軟件的解決方式:讓編譯器進(jìn)行分配,需要更加精密地分析程序
-
硬件的解決方式:當(dāng)然就是多搞幾個(gè)寄存器,當(dāng)然,我們下面介紹另一種策略——寄存器窗口。
什么是寄存器窗口?
寄存器窗口可以理解為由數(shù)量有限的幾個(gè)寄存器組成的一個(gè)小寄存器組。一個(gè)寄存器窗口由3個(gè)部分組成:
-
參數(shù)寄存器
-
局部變量寄存器
-
臨時(shí)寄存器
對(duì)于過(guò)程調(diào)用而言,寄存器組總是從一個(gè)局部移動(dòng)到另一個(gè)局部,比如A調(diào)用了B,那么A的局部變量要被保存起來(lái),然后寄存器給B的局部變量使用。
參數(shù)的傳遞是靠重疊的部分來(lái)實(shí)現(xiàn)的,前一個(gè)的寄存器窗口的臨時(shí)寄存器和下一個(gè)寄存器窗口的參數(shù)寄存器是重疊的,這樣就可以不進(jìn)行數(shù)據(jù)的移動(dòng)而進(jìn)行參數(shù)的傳遞。
這樣,過(guò)程調(diào)用就可以被看作是從一個(gè)窗口移動(dòng)到下一個(gè)窗口,而返回就是相反的過(guò)程。當(dāng)然了,一般寄存器窗口不會(huì)做成上面那種樣子,而是圓環(huán)的形式。
當(dāng)過(guò)程調(diào)用發(fā)生,當(dāng)前窗口指針CWP(Current Window Pointer)會(huì)被指向當(dāng)前活躍的寄存器窗口。如果沒(méi)有可用的窗口,那么會(huì)產(chǎn)生一個(gè)中斷,然后最晚返回的窗口會(huì)被保存到內(nèi)存,一個(gè)保存窗口指針SWP(Saved Window Pointer)會(huì)指向被保存的窗口。如果有N個(gè)窗口,那么就可以有N-1個(gè)過(guò)程調(diào)用,這很好理解,比如有2個(gè)過(guò)程A和B,對(duì)應(yīng)2個(gè)寄存器窗口,那么就可以有過(guò)程A調(diào)用B這一個(gè)過(guò)程調(diào)用。
這時(shí)候有人能就會(huì)問(wèn):局部變量這么處理,那全局變量呢?
典型的處理方式是由編譯器分配到內(nèi)存。或者也可以用一些全局變量寄存器來(lái)存儲(chǔ),不過(guò)這樣會(huì)加重寄存器的負(fù)擔(dān)。
13.3 大寄存器組和緩存對(duì)比
大寄存器組和緩存Cache看上去似乎十分相似,貌似大寄存器組也就是起到了緩存的作用,存儲(chǔ)那些經(jīng)常要用的變量(雖然寄存器要快許多),兩者有什么異同呢?
-
大寄存器組存儲(chǔ)的是所有局部變量,而cache只是最近使用的變量
-
兩者空間的使用都不夠充分,大寄存器組由于給每個(gè)窗口分配的容量都是這么多,可能會(huì)用不完;而對(duì)cache,由于每次都是讀一塊數(shù)據(jù),所以一塊中的某些數(shù)據(jù)實(shí)際上都是用不到的。
-
大寄存器組是由編譯器進(jìn)行分配,而cache是分配給最近使用的局部變量。
-
在和內(nèi)存交互的時(shí)候,大寄存器組是由過(guò)程調(diào)用的深度來(lái)決定的,如果過(guò)程調(diào)用多了就需要放入內(nèi)存了,而cache是由替換策略決定的。
-
尋址方式不同
-
大寄存器組一個(gè)周期內(nèi)能夠?qū)ぶ凡⑷〉蕉鄠€(gè)操作數(shù),而cache只能取到一個(gè)
下圖展示了大寄存器組得尋址方式,首先指令中的低位會(huì)存儲(chǔ)一個(gè)虛擬的寄存器號(hào),用來(lái)標(biāo)志尋址的是哪個(gè)寄存器,同時(shí),還需要一個(gè)窗口號(hào),用來(lái)表示是哪一個(gè)寄存器窗口。
13.4 基于編譯器的寄存器優(yōu)化
說(shuō)完了大寄存器組,我們來(lái)講講如何用編譯器對(duì)寄存器的分配進(jìn)行優(yōu)化,編譯器優(yōu)化的目的是使得需要的操作數(shù)能夠盡量存放在寄存器中,而非在內(nèi)存中,因?yàn)樽x內(nèi)存是十分耗時(shí)的。
高級(jí)語(yǔ)言是沒(méi)有顯式引用寄存器的,比如C語(yǔ)言,雖然C語(yǔ)言有register來(lái)聲明寄存器變量。事實(shí)上,編譯器是通過(guò)映射來(lái)分配寄存器的,程序中的每一個(gè)變量都會(huì)被分配給一個(gè)虛擬的寄存器,然后編譯器會(huì)將這無(wú)限的虛擬寄存器映射到有限的真實(shí)寄存器中。多個(gè)虛擬寄存器可以共享一個(gè)真實(shí)的寄存器,如果沒(méi)有真實(shí)寄存器可用,則會(huì)將變量放入內(nèi)存。
一種編譯器中經(jīng)常使用的優(yōu)化方法就是圖染色,圖染色的目的就是找到那些可以共享一個(gè)寄存器的變量,然后把他們分配到一個(gè)寄存器中,比如下面的A和D都是紅色,則可以被分配給同一個(gè)寄存器:
使用圖染色時(shí),首先給每一個(gè)可用的真實(shí)寄存器分配一個(gè)顏色(顏色相同表示分配到同一個(gè)寄存器),在這個(gè)圖中有結(jié)點(diǎn)和邊,結(jié)點(diǎn)的含義是每一個(gè)要分配的變量(或者說(shuō)虛擬寄存器),邊則表示組成邊的兩個(gè)變量的生命周期是有重疊的,比如A和B的生命周期是有部分重疊的。
過(guò)程為:可以采用回溯法的算法思想,比如從A開(kāi)始著色,給A可以涂上紅藍(lán)綠,然后再下一層到B,如果A涂了紅色,那么B只能夠是藍(lán)色或者綠色,就分了2個(gè)叉(紅色的被剪枝了,因?yàn)椴粷M足約束條件),然后再到C,依次往下。最后可以看到,F是不能夠被涂色的,于是只能分配到內(nèi)存。
13.5 RISC和CISC對(duì)比
講完RISC的寄存器優(yōu)化之后,我們總結(jié)一下RISC的特點(diǎn):
-
大部分指令在單周期內(nèi)執(zhí)行完成
-
操作大多都是寄存器到寄存器的
-
少且簡(jiǎn)單的尋址模式
-
少且固定的指令格式
-
硬連線設(shè)計(jì)(不是微程序)
-
更加有效的流水線
-
對(duì)中斷的反應(yīng)更加迅速
-
更長(zhǎng)的編譯時(shí)間以及花費(fèi)在編譯器上的精力
RISC和CISC到底哪個(gè)更好,還沒(méi)有定論,事實(shí)上現(xiàn)在很多都是混合使用的。
13.6 RISC流水線
大部分指令是兩階段的,只包含了取指和執(zhí)行,對(duì)于存取(Load and Store)則有三階段——取指(Instruction Fetch)、執(zhí)行(Execute)(計(jì)算內(nèi)存地址)和存儲(chǔ)(寄存器到內(nèi)存或者內(nèi)存到寄存器)。
圖(a)展示了沒(méi)有流水線的情況,圖(b)展示了兩階段的流水線,只包含了取指和執(zhí)行這兩個(gè)階段,如果是load指令,則將E和D都看成是執(zhí)行,可以看到這樣是存在流水線氣泡的,因?yàn)閳?zhí)行階段的時(shí)間太長(zhǎng),所以第二條的執(zhí)行要延遲一拍。而圖(c)則是三階段的,就沒(méi)有了上面的問(wèn)題,但是產(chǎn)生了新的問(wèn)題,就是將rA的值和rB的值相加時(shí),會(huì)存在依賴關(guān)系,因?yàn)樾枰鹊降诙l指令從內(nèi)存中讀到操作數(shù),也就是D結(jié)束,才能夠執(zhí)行該命令,因此這里加了一條NOOP空過(guò)一個(gè)時(shí)拍。圖(d)也是同樣的道理,只不過(guò)需要加2條NOOP。
那么像上面這種還含有跳轉(zhuǎn)指令的該如何處理呢?
可以采用延遲轉(zhuǎn)移進(jìn)行優(yōu)化,我們來(lái)看一個(gè)例子。
延遲轉(zhuǎn)移:在轉(zhuǎn)移指令之后插入一條或幾條有效的指令。當(dāng)程序執(zhí)行時(shí),要等這些插入的指令執(zhí)行完成之后,才執(zhí)行轉(zhuǎn)移指令,因此,轉(zhuǎn)移指令好像被延遲執(zhí)行了,這種技術(shù)稱為延遲轉(zhuǎn)移技術(shù),這一條或幾條指令被稱為延遲插槽。
| 100 | LOAD x,rA | LOAD X,rA | LOAD X,rA |
| 101 | ADD 1,rA | ADD 1,rA | JUMP 105 |
| 102 | JUMP 105 | JUMP 106 | ADD 1,rA |
| 103 | ADD rA,rB | NOOP | ADD rA,rB |
| 104 | SUB rC,rB | ADD rA,rB | SUB rC,rB |
| 105 | STORE A,Z | SUB rC,rB | STORE rA,Z |
| 106 | STORE rA,Z |
上表中,Normal為正常順序執(zhí)行的流水線,而Delayed是用了一條NOOP空過(guò)一個(gè)時(shí)拍,上面已經(jīng)講過(guò)了,而Optimized是使用了一些技巧進(jìn)行優(yōu)化的,我們來(lái)看一下流水線的情況:
可以看到,空過(guò)一個(gè)時(shí)拍可以解決問(wèn)題,但還是效率低了些,如果我們把轉(zhuǎn)移指令上面的那一條指令插入到轉(zhuǎn)移指令之后作為一個(gè)延遲的插槽,于是這條插入的指令還是能夠正常執(zhí)行的,且沒(méi)有依賴關(guān)系會(huì)導(dǎo)致流水線出錯(cuò),也就是說(shuō),這條指令充當(dāng)了本來(lái)的NOOP指令,但是又真正執(zhí)行了,于是效率就提高了。
今天的RISC就講到這里啦~
總結(jié)
以上是生活随笔為你收集整理的第十三章 RISC精简指令计算机的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: unity找不到报错界面
- 下一篇: 开关电源空载吱吱声_导致开关电源啸叫的六