CPU設(shè)計(jì)原理是什么
你知道cpu的設(shè)計(jì)原理嗎?下面將由學(xué)習(xí)啦小編帶大家來解答這個(gè)疑問吧,希望對大家有所收獲!
1.1 指令的執(zhí)行過程(這里沒有涉及到高級(jí)語言的編譯,所以沒有翻譯指令)
CPU的性能由哪些因素決定?我想大多數(shù)人都會(huì)知道時(shí)鐘周期這個(gè)概念,而另兩條“指令數(shù)目”,“指令所需時(shí)鐘周期數(shù)(CPI)”是并不為人所知的。而不同
的內(nèi)部架構(gòu),也便深刻的影響了CPI的大小,所以有些處理器頻率低但是處理任務(wù)更快。不過別急,一口吃一個(gè)胖子是不行的,在我們對CPU的架構(gòu)進(jìn)行探討之
前,先來看看CPU是怎么處理一條指令的。
一條指令,首先會(huì)根據(jù)程序計(jì)數(shù)器(記錄當(dāng)前運(yùn)行的指令地址,本身也是一種寄存器)從內(nèi)存中去處指令,通過指令字段的內(nèi)容,選擇讀取一個(gè)或者兩個(gè)寄存器(在
匯編語言中,一條代碼,即一個(gè)指令只能使用1或2個(gè)寄存器進(jìn)行加減乘除運(yùn)算,而寄存器,就是記錄數(shù)據(jù)的一個(gè)東西,當(dāng)然他還有更多用途,之后我們會(huì)提及)一
旦取得寄存器的操作數(shù)后,就可以對指令進(jìn)行定性,大致分為三種,存儲(chǔ)訪問,算術(shù)邏輯和分支(分支也可以叫做跳轉(zhuǎn),一般的高級(jí)語言都用if語句,判斷一些特
定條件從而進(jìn)行兩種或者更多的操作)存儲(chǔ)訪問指令需要對存儲(chǔ)單元進(jìn)行讀出或者寫入而訪問寄存器;算術(shù)邏輯指令需要將ALU(運(yùn)算器)計(jì)算得到的數(shù)據(jù)寫回寄
存器;而分支指令則會(huì)通過對數(shù)據(jù)的比較,決定是否對下條指令地址進(jìn)行修改(也就是是否進(jìn)行if語句中的or后面的語句)
話外音:一條高級(jí)語言首先會(huì)被編譯為匯編語言,之后通過指令集將其編譯為二進(jìn)制信號(hào),從而讓CPU明白它需要做哪些操作。
不要將緩存和寄存器的概念混淆,最好從百度百科上看看相應(yīng)資料。緩存我們會(huì)在第三大章進(jìn)行詳細(xì)討論。
1.2 數(shù)據(jù)通路的建立
什么叫數(shù)據(jù)通路?我想聰明的你一定知道,讓一條指令順暢執(zhí)行下去,這就是一條數(shù)據(jù)通路,它包括指令,數(shù)據(jù)存儲(chǔ)器,寄存器堆,運(yùn)算單元和加法器(加法器是對
程序計(jì)數(shù)器進(jìn)行調(diào)節(jié)的,也就是說當(dāng)前指令執(zhí)行完畢之后,加法器對程序計(jì)數(shù)器加上4,就可以切換到下一個(gè)指令地址,關(guān)于為什么加4這里不多說,在第三大章我
們會(huì)提及)。
想要構(gòu)成數(shù)據(jù)通路,首先需要一個(gè)存儲(chǔ)程序指令的地方,那么我們就需要一個(gè)存儲(chǔ)單元來存儲(chǔ)程序指令,并根據(jù)所給地址提供指令。當(dāng)前需要執(zhí)行的指令一定要放在一個(gè)存儲(chǔ)單元中,這就是我們之前提到的程序計(jì)數(shù)器(PC),然后同一個(gè)加法器增加PC的值使它指向下一條指令的地址。
得到了指令地址,就可以讓ALU對指令進(jìn)行處理,從而得到結(jié)果,而ALU想要進(jìn)行計(jì)算,就需要從寄存器獲得數(shù)據(jù)并寫入寄存器,這樣,我們就需要一個(gè)寄存器堆,來暫時(shí)存儲(chǔ)這些指令地址,信息等等。
如果是儲(chǔ)存訪問指令和算術(shù)指令的話,那么接下來只需要將寄存器的數(shù)據(jù)顯示,或者暫時(shí)儲(chǔ)存就可以了,若是分支指令,就需要對ALU的數(shù)據(jù)和寄存器的數(shù)據(jù)進(jìn)行
比較,如果為真,則執(zhí)行if語句后緊跟的語句,如果為假,就會(huì)執(zhí)行if語句中or后緊跟的語句,所以說分支指令總是延遲的,因?yàn)樵跊]有得出指令的真假時(shí)我
們不能對接下來的指令進(jìn)行處理。
1.3 指令的處理實(shí)現(xiàn)
一條指令,通過拆分(解碼器就是對指令進(jìn)行拆分,重排等操作的,使用邏輯電路從而達(dá)到了一種特殊算法),因?yàn)锳LU的處理能力是一定的,所以有些復(fù)雜指令不能在一個(gè)周期內(nèi)處理完,而需要拆分或者讓ALU利用更長的一個(gè)周期重復(fù)處理這段指令。
對于單周期實(shí)現(xiàn),和1.2節(jié)中的數(shù)據(jù)通路非常相近,如果有不熟悉的朋友可以回閱上一節(jié)。
多周期的數(shù)據(jù)通路,與單周期通路最本質(zhì)的區(qū)別有三點(diǎn):
1 指令和數(shù)據(jù)使用相同的儲(chǔ)存單元
2 只有一個(gè)ALU(也可以使多個(gè),但目前不對其進(jìn)行討論),沒有了加法器
3 每個(gè)重要的功能單元都加上了一些寄存器存儲(chǔ)輸出值,使后面的時(shí)鐘周期得到需要的信息(這是寄存器的另一個(gè)用處)。
當(dāng)一個(gè)時(shí)鐘周期結(jié)束后,我們只需要將處理得到的結(jié)果反饋給PC程序計(jì)數(shù)器,那么它就可以再次發(fā)射指令,所以就沒有必要安置加法器。
說了這么多,相信有心的朋友們就會(huì)發(fā)現(xiàn),其實(shí)我們所說的單周期指令實(shí)現(xiàn),就是早期的CISC復(fù)雜指令集計(jì)算機(jī),而多周期就是RISC精簡指令集計(jì)算機(jī)。而
CISC這個(gè)東東有兩個(gè)致命缺點(diǎn),第一,它不能夠很好的進(jìn)行流水操作(第二大章的內(nèi)容,以后詳細(xì)講解),第二,因?yàn)橹噶畹膹?fù)雜程度不一,那么如果為了性能
而使用可變時(shí)鐘周期的設(shè)計(jì),會(huì)大大增加控制器等其他單元的設(shè)計(jì)問題,而若是使用固定的時(shí)鐘頻率,又會(huì)造成極大的浪費(fèi),所以CISC現(xiàn)在已經(jīng)基本被拋棄了。
10月1日
1.4 異常
在CPU設(shè)計(jì)中,最具有挑戰(zhàn)性的一個(gè)問題,是一個(gè)程序異常(打斷程序運(yùn)行,比如錯(cuò)誤的保存了指令的結(jié)果),被中斷(來自處理器外的異常,比如內(nèi)存的讀寫錯(cuò)誤),就比如算術(shù)溢出。很多業(yè)內(nèi)人士并不區(qū)分開兩者,都稱之為中斷。
那這些異常是如何處理的呢?為了對其進(jìn)行處理,我們必須知道是那些指令引起的異常問題,目前有兩種方法,第一種需要一個(gè)狀態(tài)寄存器,其中有一個(gè)字段用于記
錄異常產(chǎn)生的原因。另一種方法利用向量中斷(用來控制轉(zhuǎn)換的終端地址)這兩種方式在這里我們不去展開細(xì)講,更多的是為了下面幾章做一點(diǎn)點(diǎn)鋪墊。
1.5 實(shí)例 奔騰處理器的內(nèi)部架構(gòu)
奔騰系列都是采用流水線設(shè)計(jì),它讓多條指令重疊從而達(dá)到更高的指令吞吐率,其時(shí)鐘周期的長度有單個(gè)功能單元的延遲決定。這里我們暫且放一放,之后還會(huì)有詳解。
Intel的IA 32指令集(指CPU能識(shí)別什么類型的指令)非常復(fù)雜,是對其實(shí)現(xiàn)控制電路的一大難點(diǎn),雖然核心內(nèi)容都是源于前幾節(jié)的內(nèi)容,但是想要出成品并不容易
IA 32的指令,有些可能用到幾十個(gè)周期,甚至超過幾百個(gè)周期的指令。例如,串行傳送指令要求計(jì)算并修改兩個(gè)不同的存儲(chǔ)地址,并且存儲(chǔ)一個(gè)字節(jié)串。而且他復(fù)雜的尋址模式也使其使其結(jié)構(gòu)實(shí)現(xiàn)難度大大提高。
而Intel的工程師巧妙地運(yùn)用多周期數(shù)據(jù)通路和微程序控制器(使用代碼而不是01來表示控制的方法),這樣,即使是需要周期數(shù)不同的指令,也會(huì)減少更多的周期損失(因?yàn)轭l率是固定的)
1.6 奔騰4的結(jié)構(gòu)
超標(biāo)量,這是在奔騰4系列CPU中引入的一種技術(shù),簡單來看,這種技術(shù)使得處理器可以有多條數(shù)據(jù)通路,每一條處理某一類型指令:存取指令,ALU計(jì)算,分
支。這樣處理器便可以在一個(gè)周期內(nèi)執(zhí)行多條指令(當(dāng)然這些都僅僅是皮毛,之后我們依舊會(huì)在第二大章進(jìn)行討論)。而所謂的微操作,便是利用某種技術(shù),讓每一
條指令分配給不同的數(shù)據(jù)通路,從而達(dá)到更高的效率。
在奔騰4中,蹤跡緩存技術(shù)就是來存儲(chǔ)微指令的,這是一種解決方案,記錄微指令將會(huì)被引入哪一條特定的數(shù)據(jù)通路。這種緩存技術(shù)比較復(fù)雜,我們會(huì)在第三大章中稍作了解。
奔騰4使用簡單的硬聯(lián)線控制和簡單數(shù)據(jù)通路,結(jié)合蹤跡緩存,獲得了令人吃驚的時(shí)鐘頻率,當(dāng)然還要得益于深度流水線的引入,不過這都是后話了。
第二章 流水線,更高更快
2.1 流水線初涉
相信對于大多數(shù)了解硬件的朋友,流水線早已不是什么陌生的詞匯了,它并不難理解。
我們先回顧一下一般的數(shù)據(jù)通路如何處理指令,首先PC會(huì)將指令地址送給ALU,ALU進(jìn)行處理將數(shù)據(jù)存儲(chǔ),然后PC值加4
,這樣就可以進(jìn)行下一個(gè)指令的處理。而流水線便是不間斷的發(fā)射指令,原本一個(gè)指令需要得到結(jié)果才會(huì)被處理,而現(xiàn)在則是讓指令充斥著整個(gè)數(shù)據(jù)通路,在ALU
處理第一條指令時(shí),第二條指令已經(jīng)進(jìn)行取值,當(dāng)?shù)谝粭l指令處理后,第二條指令立刻被送往ALU,這樣就減少了非常多的時(shí)鐘周期(一個(gè)指令需要經(jīng)過取指令,
訪問寄存器,ALU操作,訪問數(shù)據(jù),訪問寄存器這五步)(再次進(jìn)行解釋,第二步中的訪問寄存器是讓ALU得到操作數(shù)據(jù),第四步訪問數(shù)據(jù)也就是得到ALU的
計(jì)算結(jié)果所必須的一些數(shù)據(jù),例如a+b,我們需要知道a和b的值是多少。而訪問寄存器就是對PC的操作)如果這樣說還不明白的話,我們簡單打個(gè)比方,我們
做飯,需要先把菜做好,然后去煮米飯,而流水線話操作時(shí),我們可以一邊煮米飯,一邊做菜,這樣就減少了整個(gè)做飯的時(shí)間。而假設(shè)煮米飯要10分鐘,做菜要
20分鐘,那么整個(gè)流水化操作后就需要20分鐘,也就是說流水線操作的時(shí)間取決于需要時(shí)間最長的事情,在CPU中就是任務(wù)的執(zhí)行周期數(shù)取決于最復(fù)雜,處理
速度最慢的指令(比如一個(gè)超長浮點(diǎn)運(yùn)算)
附言:流水線增加的是CPU指令的吞吐率,而不是減少了單個(gè)指令執(zhí)行的時(shí)間,而且因?yàn)槟承┨厥獾膯栴},還會(huì)讓單個(gè)指令執(zhí)行時(shí)間增加,例如流水線寄存器的引入
2.2 流水線結(jié)構(gòu)的冒險(xiǎn)
我想當(dāng)看完2.1節(jié)后大家一定會(huì)說,流水線竟然如此簡單?確實(shí)流水線并不難理解,但是真正實(shí)現(xiàn)過程中人們發(fā)現(xiàn)了相當(dāng)多的問題,會(huì)引起流水線的處理停頓,我們稱為冒險(xiǎn)。
結(jié)構(gòu)冒險(xiǎn)
這是第一種冒險(xiǎn),即硬件不支持多條指令在同一個(gè)時(shí)鐘周期內(nèi)執(zhí)行。比如我們做菜的時(shí)候,因?yàn)榧依锏碾娖饕驗(yàn)榫€路的原因只能工作一個(gè),那么我們只能先煮米飯,再做菜了。
如果用CPU角度來考慮的話,如果在流水線中一個(gè)指令在該周期內(nèi)需要從內(nèi)存中取得數(shù)據(jù),而同時(shí)另一條指令需要寫入內(nèi)存,這樣,因?yàn)镈DR內(nèi)存在一個(gè)周期內(nèi)
只能執(zhí)行一次讀或者寫操作(數(shù)據(jù)總線只有一條,而對于GDDR3之后的顯示卡內(nèi)存,因?yàn)榫邆涠鄺l數(shù)據(jù)總線,可以對內(nèi)存同時(shí)進(jìn)行讀寫操作)那么這兩條指令就
造成了結(jié)構(gòu)冒險(xiǎn)。
數(shù)據(jù)冒險(xiǎn)
這是第二種冒險(xiǎn),在一個(gè)操作必須等待另一操作完成后才能進(jìn)行時(shí),那么就會(huì)造成流水線停頓。例如我們需要知道a和b,需要將兩個(gè)數(shù)相加得到c的值,之后再對
c進(jìn)行立即數(shù)操作(直接對數(shù)值進(jìn)行加減乘除運(yùn)算,而不需要讀取被加數(shù)的寄存器地址),那么必須等a和b相加后得到的數(shù)據(jù)寫到寄存器中才可以進(jìn)行下一個(gè)操
作。
控制冒險(xiǎn)
第三種冒險(xiǎn),當(dāng)處理器需要根據(jù)一條指令的結(jié)果作出決策,此時(shí)其他的指令可能在執(zhí)行中。好比一個(gè)分支操作,我們需要知道是執(zhí)行分支中哪一條指令才能進(jìn)行下一步操作,這樣接下來的指令就需要得到分支的結(jié)果才能進(jìn)行處理。
10月5日 抱歉,昨天有點(diǎn)事。。。。。。
2.2 有問題就要解決
既然流水線有那么多限制,為何不去簡化它呢?或者說直接不流水。可是經(jīng)過很多科學(xué)家的驗(yàn)證,流水線對程序提升的性能即使存在如此多的冒險(xiǎn),依舊客觀,根據(jù)流水線加速比的公式,一個(gè)5步驟處理的CPU可以提升3~4倍的性能(實(shí)則5倍,但是因?yàn)橛忻半U(xiǎn))
不去解決流水線的冒險(xiǎn)可以嗎?對于像GPU這種高度并行,數(shù)據(jù)之間關(guān)聯(lián)度低(也就是流水線的冒險(xiǎn)度較低,不易發(fā)生流水線停頓)我們完全沒有必要去理會(huì),不過
通過對指令并行的提升(ILP Instruction-Level-Parallelism )比如co-issue(相信關(guān)注GPU核心的朋友對這個(gè)
詞都會(huì)有所了解),讓兩個(gè)完全沒有關(guān)聯(lián)的數(shù)據(jù)進(jìn)行流水操作從而提升性能,當(dāng)然就目前來看ILP已經(jīng)走到了盡頭。
而CPU則不然,因?yàn)槲覀冞\(yùn)行的程序關(guān)聯(lián)性較大,如果依舊無解決辦法直接流水,那么損失的時(shí)鐘周期是相當(dāng)恐怖的,那么我們就來簡單談?wù)凜PU設(shè)計(jì)中是如何減少這種冒險(xiǎn)的。
數(shù)據(jù)旁路:這是一種解決數(shù)據(jù)冒險(xiǎn)的方法,它使用內(nèi)部的數(shù)據(jù)緩存直接提供缺少的數(shù)據(jù),而不需等待該數(shù)據(jù)到達(dá)程序員可見的寄存器或內(nèi)存才使用。實(shí)現(xiàn)它,需要用到直通技術(shù)。
為了直觀,我們先舉一個(gè)簡單的例子,a+b=c,c+d=f,我們知道了a,b,d的值,要得到c的數(shù)據(jù)才能相加。首先我們的CPU會(huì)先計(jì)算出c的值,這時(shí)
候利用直通技術(shù),將c的值直接傳給下一個(gè)指令,而不需要等到該指令結(jié)束后由PC將地址發(fā)送,那么下一條指令也便無需等待,直接可以計(jì)算。
重排指令:這里我們需要用一個(gè)簡單的例子,我們需要計(jì)算a,b,而a=c+d,b=c+e,需要的數(shù)據(jù)都在寄存器上,因?yàn)橐魉?,那么就要重?fù)獲取c的值,
如果對這段高級(jí)語言進(jìn)行編譯,那么因?yàn)閏的值需要在一個(gè)周期內(nèi)取得兩次(在正常編譯后是這種情況),所以就會(huì)發(fā)生冒險(xiǎn)。如果我們對加載c值的順序進(jìn)行調(diào)
整,就可以避免沖突。這也可以叫做亂序執(zhí)行,也就是out of order
分支預(yù)測與分支延遲:這都是用來解決控制冒險(xiǎn)的,因?yàn)樾枰玫椒种У慕Y(jié)果才可以進(jìn)行下一步,那么在一些流水級(jí)超長的CPU中(比如奔騰4)會(huì)造成相當(dāng)大的周期損失。分支預(yù)測,很簡單,就是通過某種方式對分支的結(jié)果進(jìn)行預(yù)測,那么我們也便無需等待分支的結(jié)果是真是假,直接執(zhí)行下一步便可。分支延遲也很簡單,我們先不理會(huì)分支的結(jié)果如何,對分支的兩種可能都進(jìn)行運(yùn)算,等到分支得到結(jié)果之后再舍棄。
目前流行的都是分支預(yù)測,這里拆開還能將非常多,比如BTB,我們會(huì)在下幾節(jié)進(jìn)行深入探討.
10月6日
2.4 流水線的數(shù)據(jù)通路
首先,作為進(jìn)階的思考,我們還是回顧一下一般的單周期數(shù)據(jù)通路,我們經(jīng)典的5階段的CPU,分為IF取指令,ID指令譯碼(編譯),EX指令執(zhí)行,MEM
數(shù)據(jù)內(nèi)存訪問,WB寫回。如果用5階段的CPU進(jìn)行流水,那么任意周期內(nèi),都會(huì)有一條指令充滿這5個(gè)階段,那么為了讓指令能夠得到不間斷的發(fā)射,我們必須
增加更多的寄存器,當(dāng)一條指令經(jīng)過一個(gè)階段后馬上讓PC值加上4,從而發(fā)射下一條指令,所以我們采取的方式是,在每個(gè)階段之間都要加上流水線寄存器,比如
在IF和ID段中加入一個(gè)寄存器,那么該寄存器的作用便是得到IF的指令值,反饋,使得PC值加4,而且它還要做指令數(shù)據(jù)傳輸?shù)墓ぷ?,也就是將IF的數(shù)值
傳送給ID段。那么流水線寄存器的頻率就一定要是流水線本身頻率的兩倍,所以在一個(gè)周期中,前半段時(shí)間讓PC值加上4,后半段則是傳送數(shù)據(jù)給下一個(gè)階段。
附錄:superpipeline 超長流水線。
超長流水線,也稱深度流水線,它是一種高級(jí)流水線技術(shù),在這里我們簡單來探討一下。
首先要指出的是,超長流水線并不是指ALU更多的流水線。它的含義是將一個(gè)較短階段(stage)的流水線劃分成更多階段。
其實(shí)在我一開始接觸的時(shí)候也不明白,為什么劃分更多階段能給予良好的流水性能呢?其實(shí)這一點(diǎn)不難理解,因?yàn)檫@樣,在一個(gè)周期內(nèi)流水線內(nèi)部的指令數(shù)會(huì)比原來
更多,同樣因?yàn)閯澐值母蛹?xì),頻率也更容易提升(因?yàn)榱魉€的頻率取決于速度最慢的那一階段),這樣,在計(jì)算大量數(shù)據(jù)時(shí),這種超長流水線就可以得到很好的
加速效果,但是,若是出現(xiàn)冒險(xiǎn),那么損失的時(shí)鐘周期是非常可怕的。P4當(dāng)中引入了大量的緩存(cache),目的就是讓指令所需的數(shù)據(jù)能在cache中得
到而不去等待慢吞吞的內(nèi)存(目前內(nèi)存的頻率都是200,DDR運(yùn)用了DIMM上下沿并發(fā)和數(shù)據(jù)預(yù)取的技術(shù)從而等效達(dá)到了高頻率,但是一個(gè)1.8G的CPU
依舊需要9個(gè)周期去等待內(nèi)存數(shù)據(jù))P4能達(dá)到較高的頻率,也很大程度上依靠了這種高級(jí)流水線技術(shù)。
國慶最后一天特別專題(今后2周上課所以無法更新= =)
高級(jí)話題:性能的再次提升
流水線的開發(fā),同樣造就了一個(gè)概念,叫做指令集并行,。主要通過兩種方式提高指令集的并行能力一個(gè)是增加流水線技術(shù),另一種則是設(shè)計(jì)更多的內(nèi)部元件從而在 一個(gè)流水線中的每級(jí)發(fā)射更多的指令。前者我們已經(jīng)有所探討,他就是P4中引入的superpipeline。后者就包括超標(biāo)量設(shè)計(jì),涉及到了流水線的寬 度。
我們現(xiàn)在深入探討第二個(gè)話題。這種多發(fā)射技術(shù),目前有兩種比較聰明的實(shí)現(xiàn)方法,他們的區(qū)別就是編譯器和硬件之間如何分工,由于分工主要在于某些決定是在編譯期決定的還是在運(yùn)行期決定的,所以前者稱之為靜態(tài)多發(fā)射,后者叫做動(dòng)態(tài)多發(fā)射。
靜態(tài)多發(fā)射處理器利用編譯期從而對指令進(jìn)行打包和處理各種特殊的流水線冒險(xiǎn),在靜態(tài)多發(fā)射中,我們可以將多條指令看作一條超長指令,復(fù)雜指令。同樣,因?yàn)?本身可以看作一條超長指令,那么它便被固定了長度,操作數(shù)。這就是所謂的VLIW,超長指令字,相信對R600了解的朋友一定不會(huì)陌生。
動(dòng)態(tài)多發(fā)射處理器也被稱之為超標(biāo)量處理器,在比較簡單的模型中,指令是按照順序發(fā)射,每個(gè)周期可以發(fā)射1條或多條指令,或者說不發(fā)射。非常明顯的是,這種 處理器要達(dá)到較好的性能非常依靠編譯期對各條指令的調(diào)節(jié),錯(cuò)開指令之間的依賴關(guān)系從而達(dá)到更高的發(fā)射速率。所以目前超標(biāo)量處理器會(huì)更多的在指令排序方面下 工夫。
附錄:多發(fā)射處理器的數(shù)據(jù)通路
非常簡單,我們只需要在一般的多周期數(shù)據(jù)通路上增加更多的執(zhí)行單元,比如ALU,對各種單元進(jìn)行劃分,比如A單元執(zhí)行浮點(diǎn),B單元執(zhí)行整數(shù),通過對寄存器的大小調(diào)節(jié),便可以適應(yīng)不同的指令。
第二章,完
第三章 層次結(jié)構(gòu)存儲(chǔ)器
1 導(dǎo)論
假如你是在做高數(shù)作業(yè),為了快速計(jì)算,你會(huì)把積分表放在最顯眼的地方,其次為了防止對一些積分變換的不熟練,你會(huì)放一個(gè)例題本在一旁,這樣又不會(huì)的變換就可以直接查。而如果有一個(gè)題你怎么也做不出來,就值得去求教老師。
其實(shí)本來作業(yè)應(yīng)該是我們自己做的,實(shí)在不會(huì)就去請教老師,但是借助了積分表和積分變換的例題就能更快的解決題目,而不需要去請教老師,因?yàn)檎埥汤蠋熖闊?/p>
太慢了。這樣,在CPU當(dāng)中也存在這種類似的環(huán)境,也就是說最能幫助你解決當(dāng)前問題(指令最需要的數(shù)據(jù))的應(yīng)該優(yōu)先拜訪(優(yōu)先訪問),再或者說你有兩本詞
典,一本是英語5000實(shí)用詞,另一本是牛津高階英漢詞典,查單詞的時(shí)候,我們當(dāng)然會(huì)先去查看實(shí)用詞詞典咯,大辭典查起來太慢了。
下面就得引入必備的理論知識(shí)了
時(shí)間局部性:如果一個(gè)數(shù)據(jù)項(xiàng)被引用,那在不久之后它很有可能再次使用。比如在第一個(gè)例子中,比如一個(gè)循環(huán)指令,每次循環(huán)都需要一個(gè)常量B,那么B就非常容易被調(diào)用
空間局部性:如果某個(gè)數(shù)據(jù)項(xiàng)被引用,那么不久之后與它地址相近的數(shù)據(jù)項(xiàng)可能會(huì)被引用,也就是說數(shù)據(jù)間有相依性啦
層次結(jié)構(gòu)存儲(chǔ)器,也就是按照這兩種原理所衍生的。現(xiàn)在的計(jì)算機(jī)就有緩存和內(nèi)存之分(寄存器不屬于層次結(jié)構(gòu)存儲(chǔ)器,它的目的是存儲(chǔ)目前需要使用的數(shù)據(jù),而不
是可能會(huì)使用到的數(shù)據(jù),切記切記),緩存小而快速,一般都在CPU的uncore部分,內(nèi)存就很容易理解了,在緩存和硬盤之間的,速度和容量在兩者之間其
緩沖的東東。為什么速度快容量就要小呢?這是一個(gè)邏輯電路的知識(shí),簡單的來說就是為了得到更高的速度,那信號(hào)的發(fā)射頻率必須提升,而為了得到更大的容量,
那么就必須保證信號(hào)傳輸中減少干擾。如果頻率提高,干擾就會(huì)增強(qiáng),所以兩者比較難以統(tǒng)一。
存儲(chǔ)器的層次結(jié)構(gòu)可以由多級(jí)組成,但是數(shù)據(jù)復(fù)制每次必須在兩個(gè)相鄰層次間才可以進(jìn)行,一個(gè)層次結(jié)構(gòu)中存儲(chǔ)信息的最小單元,我們稱之為快或行
(line,cache
line,眼熟吧)如果處理器需要的數(shù)據(jù)出現(xiàn)在高層(速度快,容量小的cache)的塊中,測稱之為一次命中,而命中率就是指我們需要的數(shù)據(jù)在cache
中所占的比例。缺失率也就是cache中沒有的數(shù)據(jù)占需求數(shù)據(jù)的百分比。
10月24日
1.2 緩存的簡單基礎(chǔ)知識(shí)
cache,這是專業(yè)的叫法,其實(shí)就是一種層次結(jié)構(gòu)罷了,早期的緩存都屬于片外緩存,也就是集成在主板上的,現(xiàn)在的緩存都會(huì)放到CPU的Uncore中,
也就是非核心模塊,cache本身屬于一種超高速內(nèi)存(可以如此理解),但是本身卻和內(nèi)存有較大的差距,因?yàn)閏ache屬于高速量小的存儲(chǔ)器,那么如何合
理利用這分寶貴的資源就是人們必須要掌握的了。
我們先來討論一個(gè)比較簡單的情況,假設(shè)內(nèi)存中存儲(chǔ)了1到10十個(gè)數(shù)據(jù),如果我們這時(shí)候讀取其中的4號(hào)數(shù)據(jù),那么cache將會(huì)立刻將3,4,5這些數(shù)據(jù)調(diào)
入,因?yàn)楦鶕?jù)之前我們所講的時(shí)間空間局部性,這些臨近的數(shù)據(jù)和數(shù)據(jù)本身都是很有可能被再次用到(數(shù)據(jù)第一次讀取是去內(nèi)存找而不是緩存,術(shù)語叫做強(qiáng)制性沖
突,下一次會(huì)有講到哦)再來說一個(gè),如果cache中有1~10數(shù)據(jù)中的3,4,5,如果CPU需要6號(hào)數(shù)據(jù),而cache中沒有,那么5,6,7數(shù)據(jù)就
會(huì)立即調(diào)入cache,根據(jù)局部性原理。
這時(shí)候追求細(xì)節(jié)的朋友們可能會(huì)提問,CPU怎么知道cache中有沒有所需的數(shù)據(jù)呢?如果在,又是如何找到的呢?最簡單的方法就是給內(nèi)存的每一個(gè)數(shù)據(jù)
(字)分配一個(gè)緩存的地址,每一個(gè)內(nèi)存的數(shù)據(jù)地址對應(yīng)一個(gè)確定的緩存地址(數(shù)據(jù)重復(fù)),也就是說,當(dāng)我們讀取內(nèi)存發(fā)現(xiàn)cache中含有該數(shù)據(jù)那么就會(huì)去
cache中尋找,從而縮短的很多時(shí)間。這種簡單的分配方式叫做直接映像。由于每個(gè)緩存的地址可對應(yīng)的內(nèi)存中多個(gè)不同地址,怎么才能知道所請求的數(shù)據(jù)是否
在緩存中呢?這就得引入標(biāo)記這個(gè)概念了,標(biāo)記必須包含能夠判斷緩存中的數(shù)據(jù)是否為所請求數(shù)據(jù)的地址信息。我們還需要一種辦法來判斷緩存中的確沒有有效的信
息,我們就必須知道緩存中部分標(biāo)記要被忽略,最常用的方法就是有效位,說明一個(gè)cache塊中是否有有效地址。如果這個(gè)位置沒有設(shè)置,就不能讀取其內(nèi)容。
1.3高速緩存的缺失
在接下來討論實(shí)際系統(tǒng)的高速緩存之前,我們現(xiàn)在看一看控制部件是如何處理cache miss的。首先呢,我們必須通過控制器檢測到缺失的發(fā)生,然后從低一級(jí)的緩存或內(nèi)存中取出相應(yīng)的數(shù)據(jù),如果高速緩存命中,CPU繼續(xù)照常處理,就好像什么事情都沒有發(fā)生。
命中時(shí),處理器的控制方法的修改并不太重要,而缺失時(shí)就必須附加一些工作了。cache的缺失處理由兩部分協(xié)同完成,一個(gè)是處理器的控制器,另一個(gè)就是進(jìn)
行初始化內(nèi)存訪問和重新填充緩存的獨(dú)立緩存控制器。高速緩存的缺失導(dǎo)致流水線停頓(去看第二章),與流水線中斷不同(比如你運(yùn)行QQ,結(jié)果突然間把它關(guān)掉
了),中斷發(fā)生時(shí),系統(tǒng)要求保存所有寄存器的狀態(tài),而缺失發(fā)生時(shí),我們在等待主存操作完成的期間,可以使整個(gè)機(jī)器停頓,本質(zhì)上就是凍結(jié)臨時(shí)寄存器和程序員
可見的寄存器(學(xué)編程吧,否則我講了也不會(huì)明白)的內(nèi)容,而緩存的缺失只是流水線停頓的一種情況,所以也是非常簡單的。
作為硬件討論的基礎(chǔ)我們依然要討論一下對于多周期或流水線的數(shù)據(jù)通路(進(jìn)階,必須把第一章的看完),指令發(fā)生缺失時(shí)將如何處理?如果去一條指令導(dǎo)致缺失。
那么指令寄存器的內(nèi)容無效。為了把正確的指令取到高速緩存中,必須讓存儲(chǔ)器執(zhí)行一次讀操作,由于是在流水線中,在指令執(zhí)行的第一個(gè)周期,程序計(jì)數(shù)器加一個(gè)
增量,因此產(chǎn)生高速緩存指令缺失的指令地址等于程序計(jì)數(shù)器減4.一旦有了地址,就可以只是主存執(zhí)行一次讀操作,之后等待存儲(chǔ)器的相應(yīng),然后把數(shù)據(jù)寫入高速
緩存。
說了這么多估計(jì)大家都已經(jīng)暈掉了,下面我們再來?xiàng)l理地回顧一下高速緩存去指令缺失的處理步驟
1 把最初PC的值送到存儲(chǔ)器
2 指示主存執(zhí)行讀操作
3 寫高速緩存,把從存儲(chǔ)器中讀到的數(shù)據(jù)寫入高速緩存的數(shù)據(jù)部分,把地址的高位寫入標(biāo)記域,設(shè)置有效位
4 重啟第一步,它將重新取指令,這次發(fā)現(xiàn)指令在高速緩存中。
1.4 寫操作
寫操作稍微有些不同。假設(shè)有一個(gè)存儲(chǔ)指令,我們只把數(shù)據(jù)寫入高速緩存,那么寫入高速緩存后,主存和高速緩存相應(yīng)位置的值將會(huì)變化。在這種情況下,高速緩存
和主存稱為不一致。保持一致的最簡單方法就是在緩存和主存中都寫入數(shù)據(jù),也就是寫通過(write through)。
盡管這種方法十分簡單,但是并不能提供良好的性能,所以,寫緩沖(write
buffer)就出現(xiàn)了。當(dāng)一個(gè)數(shù)據(jù)在等待被寫入主存時(shí),先把它存放在緩沖器中。在把數(shù)據(jù)寫入高速緩存和寫緩沖后,處理器繼續(xù)執(zhí)行指令。當(dāng)寫入主存操作結(jié)
束后,寫緩沖里的內(nèi)容也將被釋放。如果寫緩沖滿了,那么當(dāng)處理器執(zhí)行到一個(gè)寫操作時(shí),就得先停下來知道寫緩沖有一個(gè)空的位置。當(dāng)然,如果存儲(chǔ)器完成寫操作
的速度比處理器的速度慢,怎么緩沖也沒有用。
寫通過機(jī)制還有一種變通的方法是寫回(write back),采用寫回的方法,當(dāng)一個(gè)寫操作產(chǎn)生時(shí),新的數(shù)據(jù)僅僅被寫道高速緩存的塊中,只有當(dāng)修改過的塊被替換時(shí),才把它寫到底層的存儲(chǔ)結(jié)構(gòu)中去。
附言:其實(shí)還有很多很多操作方式,我累了。。。。。只是說了說常見的。。。。。。
11月8日發(fā)燒,帶病堅(jiān)持= =低調(diào)
(實(shí)在不忍心繼續(xù)停下了,順便打算給圖形學(xué)簡單開個(gè)頭,希望大家捧個(gè)場)
1.5 塊的定位方式與cache缺失
一直到現(xiàn)在,我們討論的將塊放入cache中,都是用最簡單的定位方式,即一個(gè)塊只能放到高速緩存中的一個(gè)位置,也就是直接映射(因?yàn)榇鎯?chǔ)器中任何一個(gè)塊
的地址都被直接映射到更高層的cache中),事實(shí)上強(qiáng)大的工程師們還有非常多的方式來安排塊,直接映射屬于一種極端,一個(gè)塊就是直接映射,這時(shí)一個(gè)塊被
精確的放在一個(gè)位置中。
另一種極端方式則是,一個(gè)塊可以放在cache中的任何位置。這種方式就是所謂的全相聯(lián)(因?yàn)榇鎯?chǔ)器中的塊可以和cache中的任何一塊聯(lián)系)。在全相聯(lián)
的cache中要找一個(gè)給定的塊,由于該塊可能被放在任何位置,必須檢測高速緩存的所有項(xiàng)。為了使檢測更加簡潔,它是由與cache中美向相關(guān)的一個(gè)比較
器并行處理完成的,這些比較器增大了晶體管的開銷,因?yàn)槿嗦?lián)只是用那些塊的數(shù)量較少的cache。
介于兩種極端的設(shè)計(jì)叫做組相聯(lián)。在一個(gè)組相聯(lián)的cache中,每個(gè)塊可以被放在固定數(shù)量(2個(gè)以上)的位置上,每個(gè)塊有n個(gè)位置可以放的組相聯(lián)cache
被稱為n路組相聯(lián)cache。。一個(gè)n路的組相聯(lián)cache有許多組構(gòu)成,每個(gè)組中都有n個(gè)塊,存儲(chǔ)器的每個(gè)塊由下標(biāo)域?qū)?yīng)到cache中唯一的組,并可
以放在此組中的任何一個(gè)塊上。因此組相聯(lián)映射是把直接映射和全相聯(lián)映射結(jié)合起來的妥協(xié)措施,這樣每個(gè)塊可以直接映射到一個(gè)組,然后檢測該組中的所有塊是否
匹配。
將這么多有毛用?大家別急,現(xiàn)在我們再次回顧一下之前的東東。
在直接映射中,一個(gè)存儲(chǔ)塊的位置是如下給出的:
塊號(hào)——cache中塊的個(gè)數(shù)
而組相聯(lián)則是:
塊號(hào)——cache中組的個(gè)數(shù)
由于全相聯(lián)中所需要的塊可以放在任何地方,所以要檢測cache中所有塊的所有標(biāo)記。
而組相聯(lián)的塊可以被放在組中的任何一個(gè)位置,所以不許檢測該組中所有的塊標(biāo)記。
直接映射的cache可以看作一個(gè)簡單的1路組相聯(lián);每個(gè)cache的一個(gè)項(xiàng)為一個(gè)塊,形成只有一個(gè)塊的組。有n項(xiàng)的全相聯(lián)cache可以看作是一個(gè)n路的組相聯(lián)cache,它只有一個(gè)組,組中有m個(gè)塊,每一項(xiàng)可以放在該組中的任何一個(gè)塊中)
提高關(guān)聯(lián)度的優(yōu)點(diǎn)是它可以提升cache的命中率,但是卻增加了命中時(shí)間,也加大了比較器的開銷。
備注:我們所說的塊就是cache line
就是這樣,命中率并不僅僅決定于緩存的容量,這是一個(gè)非常普遍的錯(cuò)誤認(rèn)知,cache相聯(lián)度同樣與處理器本身有一定關(guān)系。
終章 Pentium P4 與AMD Opteron的存儲(chǔ)器
這一章大概就是CPU設(shè)計(jì)原理的最后一節(jié)了,為了做一個(gè)完美的謝幕,當(dāng)然要用大家最關(guān)心的實(shí)際問題來結(jié)尾啦!
皓龍和奔騰在新的架構(gòu)中肯定會(huì)對一個(gè)重要的細(xì)節(jié)進(jìn)行修補(bǔ),那就是我們這一章節(jié)詳細(xì)討論的cache,兩者都附加有優(yōu)化措施來提升命中率。首先是在缺失時(shí)先 返回被請求的數(shù)據(jù),如先前小節(jié)中所描述的。二者都允許處理器在cache缺失期間,繼續(xù)執(zhí)行訪問數(shù)據(jù)cache的指令,這一技術(shù)被稱為無阻塞cache, 經(jīng)常被工程師們用在亂序執(zhí)行(看第二章去)的處理器上,來隱藏cache的缺失延遲。這種技術(shù)實(shí)現(xiàn)無阻塞有兩個(gè)特點(diǎn),第一就是指令與其他的工作來隱藏一部 分缺失延遲,第二就是重疊兩個(gè)不同缺失的延遲。
要重疊多重cache缺失的大部分缺失時(shí)間需要較高帶寬的存儲(chǔ)系統(tǒng)來并行的處理多重缺失,事實(shí)上這一點(diǎn)也被用在GPU中(當(dāng)任務(wù)一在處理時(shí),因?yàn)樾枰獙ふ?數(shù)據(jù)所以會(huì)有延時(shí),如果在任務(wù)一尋找數(shù)據(jù)的同時(shí)執(zhí)行任務(wù)二,那么這一部分延時(shí)就會(huì)被隱藏掉,同樣正因如此,GPU才被稱之為高度并行處理器,另外,這種技 術(shù)也可以在CUDA編程中應(yīng)用從而提高GPU的通用計(jì)算能力)。
奔4和皓龍的處理器都要預(yù)取指令(TLB的一種技術(shù),有些深,沒講的一部分),也都采用內(nèi)部包含的硬件預(yù)取機(jī)制來訪問數(shù)據(jù)。他們觀察數(shù)據(jù)缺失的模式,并利用此信息預(yù)測下一次取指令的信息,在循環(huán)訪問時(shí)效果很好(循環(huán)指令)。
對于微處理器的設(shè)計(jì)者們面臨的最嚴(yán)峻的挑戰(zhàn)之一,就是支持像P4和皓龍這種每個(gè)周期可以執(zhí)行多條存儲(chǔ)器指令的處理器(超標(biāo)量啊,別告訴我你忘了)。有兩種 不同的技術(shù)可以支持一級(jí)cache中的多個(gè)請求。cache可以是多端口的,允許對同一cache塊的多個(gè)訪問同時(shí)進(jìn)行。但是多端口cache一般非常昂 貴,因?yàn)槎喽丝诖鎯?chǔ)器中的RAM單元比單端口中的單元大得多(在具體說,單端口的塊不能在同一時(shí)間進(jìn)行多次操作,再多端口中增加了塊的數(shù)量)。另外一種方 案是把cache分成段,并允許多個(gè)互相獨(dú)立的存取操作對兩個(gè)不同的段進(jìn)行訪問。
關(guān)于細(xì)節(jié):AMD和Intel芯片的最大區(qū)別也許就是P4指令cache使用了蹤跡cache,而AMD皓龍使用的是更加傳統(tǒng)的指令cache。
不同于順序的將指令裝入一個(gè)cache塊中以增加空間局部性,蹤跡cache將找到的動(dòng)態(tài)的包括所有分支的指令裝入一個(gè)cache塊。這樣cache塊中 包含的就是有CPU決定的執(zhí)行指令的動(dòng)態(tài)記錄,而不是主存局部決定的靜態(tài)指令序列。由于cache中帶有分支預(yù)測,我們必須確認(rèn)分支以及地址的有效性,以 保證有效的去指令。另外P4的cache中存的是為指令而不是皓龍的IA 32指令。
很明顯,蹤跡cache需要更為復(fù)雜的cache地址映射機(jī)制,因?yàn)榈刂芬呀?jīng)不再是對齊的了。
然而蹤跡cache可以提高cache塊的利用率。例如,在傳統(tǒng)的cache中,有分支轉(zhuǎn)跳到另一個(gè)很大的塊中,這樣塊的開始一部分占用的空間就可能不被 訪問到。同樣,由分支轉(zhuǎn)跳可能跳出這樣的塊,那么塊的最后一部分就很可能被浪費(fèi)掉了。蹤跡cache僅僅存儲(chǔ)分支入口到離開記錄之間的指令,這樣避免了頭 尾的浪費(fèi)。當(dāng)然這樣也有一個(gè)弊端就是他可能在cache中多次存儲(chǔ)相同的指令,條件分支的不同選擇結(jié)構(gòu)導(dǎo)致了相同的指令成為了多個(gè)蹤跡的一部分,而每一部 分都會(huì)存儲(chǔ)在cache中。
CPU設(shè)計(jì)原理是什么
上一篇:怎么查看CPU-Z
下一篇:CPU風(fēng)扇多少錢