簡述影響指令執(zhí)行時(shí)間的主要不確定因素_第1頁
簡述影響指令執(zhí)行時(shí)間的主要不確定因素_第2頁
簡述影響指令執(zhí)行時(shí)間的主要不確定因素_第3頁
簡述影響指令執(zhí)行時(shí)間的主要不確定因素_第4頁
簡述影響指令執(zhí)行時(shí)間的主要不確定因素_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

簡述影響指令執(zhí)行時(shí)間的主要不確定因素 處理器流水線機(jī)制論壇上經(jīng)常有人問,某段語句的執(zhí)行時(shí)間是多少;或者是某幾段語句,那段執(zhí)行時(shí)間快。絕大多數(shù)朋友也會(huì)帶著好奇的觀點(diǎn),在旁邊觀戰(zhàn);通常的回答是:你看芯片手冊(cè)吧。類似的帖子和類似的回答很多,但是很少有人能把這個(gè)問題回答的清晰和徹底。我覺得,這種提問本來就不專業(yè),答案也不唯一。至于原因?因?yàn)橐粭l指令的執(zhí)行時(shí)間不僅取決于處理器的頻率,還取決于許多處理器以外的因素。芯片手冊(cè)上指令的執(zhí)行時(shí)間,通常是不考慮外界因素的:不考慮總線沖突、不考慮內(nèi)存延遲、不考慮高速緩存機(jī)制、不考慮流水線的相關(guān)性等。這里我打算分兩次主要介紹下,高速緩存和處理器的流水線機(jī)制如何影響指令的執(zhí)行時(shí)間的。本次先介紹流水線相關(guān)機(jī)制。1.流水線技術(shù)現(xiàn)代絕大多數(shù)的處理器在某個(gè)時(shí)刻,并不是只處理一個(gè)指令,而是按照流水線的形式處理,這和我們實(shí)際生活中,車間里的流水線是一個(gè)原理。下面我們假設(shè)某個(gè)處理器有三級(jí)流水線:譯指/運(yùn)算/寫存。這里只是假設(shè),不要對(duì)號(hào)入座。譯指:處理器讀取并分析指令的功能,比如mov是賦值,add是加法;譯指為下一步的運(yùn)算提供數(shù)據(jù)輸入和選擇相應(yīng)的硬件單元。運(yùn)算:處理器進(jìn)行加減乘除移位比較等等運(yùn)算,不需要運(yùn)算的指令進(jìn)行下一步驟排隊(duì)”寫存:處理器將運(yùn)算單元的輸入寫回內(nèi)存或者寄存器,并更新pc。假設(shè)該處理器正在處理四條指令A(yù)BCD。每條指令又有三個(gè)處理過程,即譯指/運(yùn)算/寫存。某個(gè)時(shí)刻處理器的狀態(tài)如下:流水線某個(gè)時(shí)刻各處理單元的狀態(tài)為:|C指令譯指|B指令運(yùn)算|A指令寫存|一個(gè)coreclock(處理器時(shí)鐘)后,流水線的狀態(tài)為:|D指令譯指|C指令運(yùn)算|B指令寫存|流水線的每個(gè)階段,都可以設(shè)計(jì)出獨(dú)立的硬件單元,這些單元之間可以并行運(yùn)行,從而提高了處理器的并行處理能力。我們假設(shè)流水線的每個(gè)階段需要耗時(shí)1ns,一條指令的完整執(zhí)行時(shí)間就是3ns;不采用流水線時(shí),指令的完整執(zhí)行時(shí)間是3ns。那么,流水線每1ns有一條指令執(zhí)行完畢,而不采用流水線則3ns才執(zhí)行完畢一條完整的指令;可以看出使用流水線技術(shù)后的執(zhí)行效率是原處理器的3倍。(該例子只說明流水線的優(yōu)勢(shì),實(shí)際并不那么簡單的數(shù)學(xué)公式)但是,流水線各個(gè)階段的實(shí)現(xiàn)需要考慮很多因素。一方面,流水線的多個(gè)階段之間相互獨(dú)立,前一階段的執(zhí)行輸出是后一階段的執(zhí)行輸入,所以必須有一個(gè)地方存儲(chǔ)前一階段的輸出,這樣就必須在流水線的各階段之間插入''暫存器〃。通常它是一類寄存器,對(duì)該寄存器的訪問是需要時(shí)間的。另一方面,流水線各個(gè)階段的功能劃分和執(zhí)行時(shí)間的劃分會(huì)影響流水線的性能。這里不討論流水線的劃分了,人_人水平不夠。那么,流水線是否會(huì)任何時(shí)間都這樣平穩(wěn)執(zhí)行呢?有些主要并常見的因素會(huì)影響指令的有條不紊執(zhí)行。2.數(shù)據(jù)相關(guān)和數(shù)據(jù)冒險(xiǎn)所謂相關(guān),指前后的指令存在某種關(guān)聯(lián);相關(guān)分為數(shù)據(jù)相關(guān)和控制相關(guān)。我們先介紹數(shù)據(jù)相關(guān)。比如下面的程序:main(){inta,b;a=3;main[0xe3a01003]*movr1,#3b=a;000080e0[0xe1a02001]movr2,r1}以上程序是在ADS1.2上的編譯輸出,變量a對(duì)應(yīng)寄存器r1,變量b對(duì)應(yīng)寄存器r2??梢钥闯?,第5行語句和第4行的語句存在直接關(guān)系。以我們前面介紹的三級(jí)流水線來看,變量a(寄存器「1)的值必須要等到寫存完畢后,其值才變?yōu)?;而緊接著的語句“movr2,r1〃是把變量a的值賦值到變量b(寄存器「2)里,若等到對(duì)變量a賦值的語句寫存完畢了,那么對(duì)變量b的賦值語句也運(yùn)算完畢了,顯然運(yùn)算階段輸入的數(shù)據(jù)可能不是3。這里,前者的輸出數(shù)據(jù)是后者的輸入數(shù)據(jù),我們把這種情況叫:數(shù)據(jù)相關(guān)。處理器在處理數(shù)據(jù)相關(guān)時(shí),可能會(huì)導(dǎo)致的計(jì)算失誤叫數(shù)據(jù)冒險(xiǎn)(所以,處理器必須避免數(shù)據(jù)冒險(xiǎn))。為了避免處理器真正產(chǎn)生這樣的數(shù)據(jù)冒險(xiǎn),我們可以把上面的例子修改下:main()TOC\o"1-5"\h\z{inta,b;□a=3;main[0xe3a01003]*movr1,#3asm{nop;000080e0[0xe1a00000]nopnop}000080e4[0xe1a00000] nopb=a;000080e8[0xe1a02001] mov r2,r1}我們?cè)谡Z句“勞3”和“b=a”之間人為加上了nop指令色囂指令,處理器不會(huì)做任何顯示的事情)。那么,當(dāng)語句“勞3”執(zhí)行完寫存時(shí),語句“b=a”才準(zhǔn)備開始譯指。這樣,b就能從對(duì)應(yīng)的寄存器中取得正確的值了。通過上面的例子,我們知道,要避免處理器產(chǎn)生數(shù)據(jù)冒險(xiǎn),可以加Anop指令。但是,上層開發(fā)者如何明白這些道理呢?。。∷?,處理器可能會(huì)幫助你加入類似的操作(不一定是nop指令)。下面我們介紹處理器通常的做法。另外,不光是寄存器在前后指令引用可能產(chǎn)生數(shù)據(jù)相關(guān),內(nèi)存數(shù)據(jù)、其他內(nèi)部寄存器等都可能產(chǎn)生數(shù)據(jù)相關(guān)。如何解決數(shù)據(jù)相關(guān)是處理器設(shè)計(jì)者考慮的事情,但是我們看到:處理器手冊(cè)上講到某個(gè)指令的執(zhí)行時(shí)間時(shí),不會(huì)提到這些。就意味著,若干匯編執(zhí)行完畢后,你會(huì)發(fā)現(xiàn)時(shí)間總和不是手冊(cè)上的時(shí)間總和!3.流水線停滯處理器為了自動(dòng)處理數(shù)據(jù)相關(guān),通常會(huì)采取流水線停滯的做法。流水線停滯時(shí),處理器會(huì)暫?!毕嚓P(guān)指令的后續(xù)指令,止到冒險(xiǎn)行為不可能發(fā)生為止。我們一聽就覺得這個(gè)棘手吧。處理器通常需要盡早的發(fā)現(xiàn)數(shù)據(jù)相關(guān),從而盡早的把后續(xù)指令阻塞在譯指階段。阻塞在譯指階段,處理器可以放棄這條相關(guān)的指令,轉(zhuǎn)而插入一個(gè)(每個(gè)周期插入一個(gè),但pc值不因此增加)nop指令。當(dāng)冒險(xiǎn)條件不滿足時(shí),不再插入nop指令。在前面我們介紹使用nop指令可以解決數(shù)據(jù)冒險(xiǎn),很多處理器會(huì)設(shè)計(jì)為這樣。同時(shí),插入的這個(gè)nop指令叫氣泡。所以,使流水線停滯可以解決數(shù)據(jù)相關(guān)的問題。但是,處理器停滯不是解決數(shù)據(jù)相關(guān)的唯一答案。比如,采取流水線前后的數(shù)據(jù)反饋和轉(zhuǎn)發(fā)等機(jī)制,不過這樣會(huì)加大設(shè)計(jì)難度。通常很多處理器會(huì)將停滯和轉(zhuǎn)發(fā)等技術(shù)綜合使用。要注意,流水線停滯和插入氣泡,實(shí)際上是有區(qū)別的。這里為了簡便,我們把插入氣泡也視著流水線停滯。本節(jié)主要是想讓讀者明白,我們查處理器的指令手冊(cè)來知道指令的執(zhí)行時(shí)間并不可靠??刂葡嚓P(guān)和控制冒險(xiǎn)前面講到處理器會(huì)因?yàn)閿?shù)據(jù)相關(guān)可能改變已有指令的有條不紊執(zhí)行,那么當(dāng)遇到分支指令時(shí)呢?我們先看下面例子:4main()5{inta=2;main[0xe3a01002]*movr1,#2if(a==1)000080e0[0xe3510001]cmpr1,#1000080e4[0x1a000000]bne0x80ec;(main+0x10){a=3;000080e8[0xe3a01003]movr1,#310}11}000080ec[0xe3a00000]movr0,#0000080f0[0xe1a0f00e]movpc,r14上面的例子同樣是在ADS1.2上的編譯結(jié)果。首先把變量a的值賦為2,然后判斷變量a的值是否為1,若a為1則把a(bǔ)賦值為3。假設(shè)指令“movr1,#2”為指令(1);指令“cmpr1,#1”為指令(2);指令“bne0x80ec”為指令(3);指令“movr1,#3”為指令(4);指令“movr0,#0”為指令(5)。同樣,依前面講到的三級(jí)流水線來看。當(dāng)指令(2)準(zhǔn)備執(zhí)行寫存階段時(shí),指令(4)是否執(zhí)行呢??擺在處理器面前的是兩條選擇:譯指指令(4)?譯指指令(5)?我們把前面這種分支語句的相關(guān)叫控制相關(guān)。同樣,處理器可能會(huì)因?yàn)榭刂葡嚓P(guān)而產(chǎn)生錯(cuò)誤的行為叫控制冒險(xiǎn)。如果你注意思考,你會(huì)發(fā)現(xiàn),使用流水線停滯同樣可以解決控制相關(guān)。不錯(cuò)!所以流水線停滯是一個(gè)影響指令執(zhí)行時(shí)間的常見原因。實(shí)際實(shí)現(xiàn)時(shí),處理器也可能會(huì)在某些控制相關(guān)停滯流水線。F面介紹處理器通常還會(huì)用什么樣的做法來解決控制相關(guān)呢?分支預(yù)測(cè)前面介紹了控制相關(guān),產(chǎn)生控制相關(guān)的情況依處理器不同可能有不同,但是分支語句通常會(huì)產(chǎn)生控制相關(guān);另外,函數(shù)調(diào)用和函數(shù)返回會(huì)產(chǎn)生控制相關(guān);允許直接對(duì)pc賦值的處理器,在對(duì)pc賦值時(shí),產(chǎn)生控制相關(guān)。所以這里我要強(qiáng)調(diào)依處理器不同,匯編指令有所不同。比如同樣是函數(shù)返回:X86采用ret指令;而ARM的MOV指令也可以用于函數(shù)返回(見前一節(jié)例子的最后一句匯編)??偟膩碚f,流水線如果在譯指(流水線前端)不容易判斷的分支,那么處理器就會(huì)進(jìn)行一個(gè)預(yù)測(cè)。這種預(yù)測(cè)就是分支預(yù)測(cè)。而對(duì)某些指令,流水線一看就知道要跳轉(zhuǎn)的,那么流水線通常會(huì)停滯,等待正確的pc確定。所以,我又要強(qiáng)調(diào)不同處理器了?。。。〖热皇穷A(yù)測(cè),那么就會(huì)存在預(yù)測(cè)失誤的時(shí)候。預(yù)測(cè)失誤,處理器就會(huì)嘗試恢復(fù)正確的執(zhí)行“軌跡〃。要恢復(fù)正確的執(zhí)行'軌跡〃就勢(shì)必會(huì)做額外的事情。我們把這種由于預(yù)測(cè)錯(cuò)誤,而帶來的額外開銷就叫預(yù)測(cè)錯(cuò)誤懲罰。當(dāng)處理器預(yù)測(cè)正確分支時(shí),沒多大改變,繼續(xù)往前執(zhí)行。但是,當(dāng)預(yù)測(cè)錯(cuò)誤時(shí),處理器必須丟棄預(yù)測(cè)部分的執(zhí)行結(jié)果,并恢復(fù)回剛才的預(yù)測(cè)點(diǎn),重新在正確的pc處取指令開始執(zhí)行。根據(jù)很多資料介紹,預(yù)測(cè)錯(cuò)誤的處罰開銷,相比停滯的開銷大很多。所以,處理器在處理預(yù)測(cè)的時(shí)候,會(huì)比較謹(jǐn)慎,這個(gè)部分也是處理器性能的體現(xiàn)。我們可以發(fā)現(xiàn),一個(gè)循環(huán)次數(shù)龐大的循環(huán)代碼,在一個(gè)好的分支預(yù)測(cè)處理器上運(yùn)行和在一個(gè)預(yù)測(cè)能力差的處理器上運(yùn)行,他們的時(shí)間可能會(huì)差距相當(dāng)遠(yuǎn)。通常,在沒有分支預(yù)測(cè)的處理器上,會(huì)采用停滯等簡單做法。預(yù)測(cè)的算法也有多種,限于水平,這里不能多介紹了。請(qǐng)大家見諒。通過前面幾節(jié)的介紹,我們知道:表面平靜的湖面,湖面以下可能波濤洶涌。它可能無形的影響你的代碼運(yùn)行時(shí)間。亂序執(zhí)行處理器前面主要介紹流水線對(duì)指令執(zhí)行時(shí)間的影響,后面做為附加介紹吧。在前面的章節(jié),我們主要介紹的傳統(tǒng)的處理器的流水線。當(dāng)編譯器把指令選取完成后,處理器只能被動(dòng)的運(yùn)用各種技巧來提高運(yùn)行效率。有一種處理器,它可以根據(jù)自己的算法來重新選擇指令的執(zhí)行先后,從而提高執(zhí)行效率。這種處理器就叫亂序執(zhí)行處理器。不管亂序處理器如何“亂〃,它必須保證執(zhí)行結(jié)果和不'亂〃的結(jié)果一致。比如,數(shù)據(jù)相關(guān)的例子。如果語句“b=a"之后,有其他不產(chǎn)生任何與正在執(zhí)行的指令相關(guān)的指令時(shí),亂序執(zhí)行的處理器就可能先執(zhí)行這樣的不相關(guān)指令了;等冒險(xiǎn)消失后,再執(zhí)行語句'b=a"0這樣,亂序執(zhí)行,提高了流水線的利用率,流水線減少了停滯的概率。不過亂序?qū)Ψ种дZ句的效果應(yīng)該不理想。所以,當(dāng)你在處理器手冊(cè)上找指令的執(zhí)行時(shí)間時(shí),再當(dāng)這個(gè)處理器還是亂序執(zhí)行的處理器時(shí),這個(gè)時(shí)間越來越偏離理論值。超標(biāo)量處理器前面知道了流水線的一些知道,也許有的人會(huì)想到使用級(jí)數(shù)很多的流水線來提高流水線效率,我們把這種流水線級(jí)數(shù)的多少叫深度。超標(biāo)量處理器通常就是指這種流水線深度較深的處理器,不過具體多少深度才叫超標(biāo)量處理器,我也沒找到具體定義。公認(rèn)的奔騰系列處理

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論