日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

超标量处理器设计 姚永斌 第10章 指令提交 摘录

發布時間:2024/8/1 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 超标量处理器设计 姚永斌 第10章 指令提交 摘录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

10.1?概述

在超標量處理器中,指令在處理器內部執行的時候,是不會按照這種嚴格的串行方式執行的。但是處理器想要正確地執行程序,就必須按照程序中串行順序,則一般在超標量流水線中增加最后一級階段,稱為提交commit。

當一條指令到達提交階段后,會將這條指令在重排序緩存中標記為已完成的狀態,需要注意的是,這個狀態只表示這條指令已經計算完畢,并不表示它可以離開流水線。

只有在重排序緩存中最舊的那條指令變為已完成的狀態時,這條指令才允許離開流水線,并使用它的結果對處理器的狀態進行更新,此時稱這條指令退休retire了。從這個過程可以看出,一條指令可能需要在流水線的提交等待一段時間,才可以從流水線中退休,而重排序緩存是完成這個功能的關鍵部件,因此它也是流水線的提交階段最重要的一個部件。

由于分支預測失敗和異常等原因,到達提交階段的指令并不一定代表這條一定是正確的。

只有這條指令之前進入到流水線中的所有指令退休了,并且這條指令已經處于已完成的狀態時候,它才可以退休而離開流水線。

在一條指令沒有退休之前,它的狀態都是推測的,只有這條指令真正退休而離開流水線的時候,才可以將它的結果更新到處理器的狀態中國,這樣即使有分支預測失敗或者異常,也不會將錯誤狀態暴露給程序員。

流水線的分發階段是處理器從順序執行到亂序執行的分界點,那么,流水線的提交階段又將處理器從亂序狀態拉回到順序執行的狀態了。不管超標量處理器內部發生了怎樣的事情,從處理器外部看來,它總是按照程序中指定的順序執行的,任何預測技術所產生的錯誤,在處理器內部都會解決掉,不會將這些錯誤的狀態表現出來。

維持程序執行的串行性,也是精確異常所要求的,精確異常的定義是當一條指令發現異常時,這條指令前面的所有指令都已經完成,而這條指令及其后面的所有指令都不應該改變處理器的狀態。

對于一個N-way的超標量處理器來說,流水線的提交階段每周期至少需要將N條指令退休,這樣才能保證流水線不會被堵塞。

10.2?重排序緩存

10.2.1?一般結構

ROB本質是一個FIFO,它當中存儲了一條指令的相關信息,例如這條指令的類型,結果,目的寄存器和異常的類型。

?ROB的容量決定了流水線最多同時執行的指令個數,表項的內容包括

(a)Complete:表示一條指令是否已經執行完畢;

(b)Areg:指令在原始程序中指定的目的寄存器,它以邏輯寄存器的形式給出;

(c)Preg:指令的Areg經過寄存器重命名之后,對應的物理寄存器編號;

(d)OPreg:指令的Areg被重命名新的Preg之前,對應的舊的Preg,當指令發生異常而進行狀態恢復時,會使用到這個值;

(e)PC:指令對應的PC值,當一條指令發生中斷或者異常時,需要保存這條指令的PC值,以便能夠重新執行程序;

(f)Exception:如果指令發生了異常,會將這個異常的類型寫到這里,當指令要退休時候,會對這個異常進行處理;

(g)Type:指令的類型會被記錄在此,當指令要退休時候,不同類型的指令會有不同的動作,例如store指令要寫D-Cache,分支指令要釋放Checkpoint。

指令一旦在流水線分發階段占據了ROB中的一個表項,這個表項的編號會一直隨著這條指令在流水線中流動,這樣指令在之后的任何時刻,都可以知道如何在ROB中找到自己。

一條指令一旦變為ROB中最舊的指令,使用head?pointer來指示最舊的指令,并且它的complete狀態位也為1,就表示這條指令已經具備退休的條件了。

一般而言,在流水線的分發階段,每周期最多可以進入ROB的指令個數會等于ROB每周期最多可以退休的指令個數,這樣可以保證流水線的暢通。

10.2.2?端口要求

處理器在執行過程中,從ROB中最舊的一些指令中(由head?pointer指定),選擇那些已經變味complete狀態,使其從流水線中退休。

?需要對ROB中最舊的指令開始連續的四個complete信號進行判斷,如果某個complete信號為0,那么它后面的所有指令都不允許在本周期退休。

對于一個4-way的超標量處理器來說,ROB至少需要支持4個讀端口,但是這遠遠不是ROB真正需要的端口個數,流水線的其他階段還對ROB有著端口需求,它和處理器所采用的架構有關系,如果處理器采用ROB進行寄存器重命名的方式,此時對ROB的端口需求是最多的,這些端口包括:

(a)在流水線的寄存器重命名階段,需要從ROB中讀取4條指令的源操作數,因此需要ROB至少支持8個讀端口。

(b)在流水線的分發階段,需要向ROB寫入四條指令,因此需要ROB支持4個寫端口。

(c)在流水線的寫回階段,需要向ROB寫入最少4條指令,之所以使用最少的這個詞,是因為很多處理器的issue?width要大于machine?width,處理器會放置更多的FU來提高運算的并行度,這樣導致每周期運算得到的結果要打4個。

ROB需要支持12個讀端口和最少8個寫端口,這種多端口的FIFO在面積和延遲方面很難進行優化,這也是采用ROB進行寄存器重命名的架構所面臨的最大問題之一;ROB會成為處理器中最繁忙的部件。

10.3?管理處理器的狀態

在超標量處理器內部有兩個狀態,一個是指令集定義的狀態,例如通用寄存器的值,PC值以及存儲器的值,將這個狀態稱為Architecture?state;還有一個狀態時超標量處理器內部的狀態,例如重命名使用的物理寄存器、重排序緩存、發射隊列和store?buffer等部件的值,這些狀態是處理器在運行過程中產生的,由于亂序執行的原因,它總是超前于指令集定義的狀態。將處理器內部的狀態稱為speculative?state。一條指令只有在退休的時候才會更新處理器中指定集定義的狀態,就好像處理器使按照串行的順序執行程序一樣。

只有一條指令滿足退休條件,變為ROB中最舊的指令,已經處于complete狀態,并且沒有異常發生,這才能夠將這條指令對應的處理器內部狀態更新到指令集定義的狀態中。

邏輯寄存器之外的其他寄存器都屬于處理器內部狀態,都不應該從處理器外部看到。除了指令集定義的資源,例如PC寄存器、存儲器或者通用寄存器等部件來說,其他的資源都屬于處理器內部的狀態。

?對于指令集中定義的絕大部分指令,都會更改處理器的狀態,例如普通的運算指令改變通用寄存器的值,訪問存儲器的指令改變存儲器和通用寄存器的值,分支指令改變PC寄存器的值。

例如對于采用將通用寄存器擴展為寄存器重命名的架構,需要將目的寄存器的值從物理寄存器搬移到通用寄存器;對于采用統一的物理寄存器進行重命名的架構需要將目的寄存器在物理寄存器堆中標記為外界可見的狀態;store指令需要將Store?buffer中對應的值寫到D-Cache中;分支指令預測失敗進行狀態恢復,并且拋棄掉流水線中錯誤的指令,重新從正確的地址開始取指令,將它所占用的checkpoint資源進行釋放;異常指令則會使處理器拋棄流水線當中所有指令,跳轉到相應的異常處理程序的入口。

在超標量處理器中,根據架構的不同,會對應著不同的方法來管理指令集定義的狀態,主要兩種方法:

(a)使用ROB管理指令集定義的狀態;

(b)使用物理寄存器管理指令集定義的狀態

10.3.1?使用ROB管理指令集定義的狀態

對于采用ROB進行寄存器重命名的架構,一條指令在沒有退休之前,都會使用ROB來保存指令的結果,當指令退休的時候,這條指令的結果可以對指令集定義的狀態進行更新,此時會將這條指令的結果從ROB中搬移到指令集定義的邏輯寄存器中。在這種架構中,邏輯寄存器是物理上真實存在的,由于在邏輯寄存器中存儲了所有退休的指令對應的目的寄存器的值,因此這種方法也被稱為Retire Register File,簡稱RRF。

ROB包括了兩個主要部分,即指令信息和指令結果。在指令信息中記錄了指令的類型、指令執行的狀態以及指令的目的寄存器等內容,在指令結果中記錄了指令產生的結果。

這種設計本質上利用ROB作為物理寄存器,可以直接將4條指令在ROB的地址作為它們經過寄存器重命名之后的物理寄存器,因此使用ROB來管理指令集定義的狀態,可以簡化寄存器重命名的過程。

在一般情況下,使用ROB來管理指令集定義的狀態,都會對應著使用數據捕捉的結構來發射,因為在這種方法中,當一條指令退休的時候,需要將這條指令的結果從ROB中搬移到通用寄存器中,以后的指令如果想要使用這條指令的結果,就需要從通用寄存器中進行讀取。這樣,一個寄存器在它的生命周期內會存在兩個地方,如果使用數據捕捉的方法,當一條指令的結果在流水線的執行階段被計算出來之后,會將這個結果送到旁路網絡中,這樣payload RAM就可以捕捉到這個結果,也就是說,在發射隊列中,所有使用這個結果作為操作數的指令都會得到這個值,這些指令被仲裁電路選中的時候,直接從payload RAM就可以得到所有源寄存器數了,而不需要關心這個寄存器此時是在ROB中還是通用寄存器中。因此,payload RAM是采用數據捕捉結構的必要部件,當指令被進行重命名的時候,會訪問重命名映射表,如果發現源寄存器的值已經被計算出來,那么直接可以從ROB或者通用寄存器中讀取這個值,然后寫到payload RAM中,等待從旁路網絡中捕捉這個值。如果這個寄存器的值還沒有被計算出來,就將這個寄存器在ROB中的地址寫到payload RAM中,等待從旁路網絡捕捉這個值。

使用ROB進行寄存器重命名,并管理指令集定義的狀態,是和數據捕捉的發射方式正好匹配的。

10.3.2?使用物理寄存器管理指令集定義的狀態

這種方式使用一個統一的物理寄存器堆,指令集中定義的所有邏輯寄存器都混在這個寄存器堆中。當然,未來進行寄存器重命名,在它當中包含了更多的寄存器,當一條指令被寄存器重命名之后,它的目的寄存器就和一個物理寄存器產生了對應關系,優點在于:

(a)當指令從ROB中退休的時候,不需要將指令的結果進行搬移,它仍舊會存在于物理寄存器中,也就是說,一旦指令的源操作數被確定存在那個地方,以后就不會再變化了,這樣便于處理器實現低功耗設計。

(b)在基于ROB進行狀態管理的方式中,需要從ROB中開辟空間來存放指令的結果,但是在程序中,有相當一部分的指令并沒有目的寄存器,例如store指令,比較指令和分支指令,因此ROB中會有一部分空間是浪費的。使用物理寄存器進行狀態管理則避免了這樣的問題。這種方式只對目的寄存器的指令分配空間,其他不存在的目的寄存器的指令,不會對應任何物理寄存器。因此使用這種方式,占用的物理寄存器個數小于此時ROB中指令的個數。

(c)ROB是一個集中管理的方式,所有指令都需要從中讀取操作數,同時所有的指令也需要將結果寫到其中,再加上ROB空間的占用和回收都需要讀寫端口的支持,因此這需要大量的讀寫端口,會使得ROB變得非常臃腫,嚴重拖累處理器的速度。

缺點是:造成寄存器重命名的過程比較復雜,在使用ROB進行狀態管理的時候,只需要將一條指令寫入到ROB就可以完成重命名的過程,當這條指令順利地離開流水線的時候,就自然釋放了這個映射關系,而使用物理寄存器進行狀態管理的方式中,需要一個額外的表格來存放那些物理寄存器是空閑的,并且重命名映射的關系建立和釋放過程都是比較復雜的。

10.4?特殊情況的處理

由于現代超標量處理器采用了很多預測方法來執行指令,并不是流水線中所有的指令都可以退休,例如分支預測失敗和異常。在流水線的提交階段需要重點關注的指令還有store指令,由于它只有在退休的時候才可以真正地改變處理器的狀態。

10.4.1?分支預測失敗的處理

發現分支預測失敗后,處理器的狀態恢復的過程可以分為兩個獨立的任務,前端的狀態恢復和后端的狀態恢復,它們是以流水線的寄存器重命名階段為分界的。前端的狀態恢復是比較簡單的,只需要將流水線中重命名階段之前的所有指令都抹掉,將分支預測推測其中歷史狀態表進行恢復,并使用正確的地址來取指令即可;后端恢復復雜一點,需要將處理器的所有內部組件,例如issue?queue、store?buffer,和ROB等錯誤的指令都抹掉,還需要將重命名映射表RAT進行恢復,以便將那些錯誤的指令對RAT的修改進行修正,同時被錯誤的指令所占據的物理寄存器和? ? ? ? ROB的空間也需要被釋放。

當發現分支預測失敗時,大部分的恢復任務都是對寄存器重命名的相關部件進行的,因為大部分錯誤錯誤路徑上的指令都經過了這一步。重命名方式的修復如下:

(1)在基于ROB進行重命名的架構中進行狀態修復

在基于ROB進行寄存器重命名的架構中,存在一個真正的寄存器堆,它和指令集中定義的所有寄存器是一一對應的,它成為ARF。

一條退休的指令將目的寄存器的值從ROB搬移到ARF中,并不一定表示以后的指令就需要從ARF中讀取這個寄存器的值。

在ROB中的每條指令都會檢查自身是否是最新的映射關系,只有當一條指令從ROB中退休的時候,發現自身也是最新的映射關系,這樣才能將RAT中對應的內容改為ARF狀態。

從ROB中退休的一條指令如何才能檢查自身是不是最新的映射關系呢?可以在這條指令退休的時候,使用它的目的寄存器來讀取RAT,讀出這個邏輯寄存器此時對應的ROB?pointer。

在流水線中發現分支預測失敗時,此時流水線中有一部分指令時分支指令之前進入流水線的,它們可以繼續被執行,因此但發現分支指令預測失敗時,并不馬上進行狀態修復,而是停止取新的指令,讓流水線繼續執行,這個過程稱為將流水線抽干drain?out。

這種基于ROB進行寄存器重命名的方法,不僅重命名過程本身易于實現,當分支預測失敗時進行的狀態恢復也是比較簡單的,硬件小高也比較少。

(2)在基于統一的PRF進行重命名的架構中進行狀態修復

在這種架構中,流水線中存在兩個重命名映射表,一個在流水線的寄存器重命名階段使用,它的狀態時推測的,稱作前段RAT;另一個是在流水線提交階段使用的,所有從流水線中退休的指令,如果它存在目的寄存器,都會更新這個表格,因此它永遠都是正確的,稱它為后端RAT。

等到分支指令之前的進入到流水線的指令(包括分支指令本身)都順利地離開流水線的時候,此時在流水線中所有的指令都是處在錯誤的路徑上,可將流水線中所有指令全部抹掉,然后將后端RAT全部復制到寄存器重命名階段使用的RAT,這就完成了RAT狀態恢復,此時就可以從正確的地址開始取地址執行。

也會遇到當分支指令之前存在D-Cache?miss指令,分支指令等待時間過長而導致分支預測失敗的懲罰過大的情況。

如果在流水線中發現分支預測失敗時,可以馬上進行狀態恢復,而不需要等待分支指令從流水線中退休,這樣就加快速度,從而減少懲罰。

使用checkpoint的方法可以快速進行狀態恢復,這種方法會在每條分支指令改變處理器的狀態之前,將處理器的狀態保存起來,例如在分支指令以后后面的指令對重命名映射表更改之前,將這個表格的內容保存起來,這樣在以后的時間發現分支預測失敗的分支指令時,可以使用這條分支指令的編號到流水線中錯誤路徑上的指令都抹掉,同時使用checkpoint資源將處理器的狀態進行恢復,然后就可以從正確路徑上取指令執行了。

分支指令個數很可能增加,但是checkpoint個數很難隨之增加。解決方法是對那些分支進行checkpoint也進行預測,因為很多分支指令的預測正確率很高,為它分配checkpoint資源,絕大部分時間都是浪費的。

當一條分支指令沒有分配checkpoint資源,但是最后發現這條分支預測失敗時,如何對處理器進行狀態恢復,當然可以等待這條分支指令退休的時候。利用ROB將重命名映射表進行恢復了,較之使用checkpoint方法,這種方法肯定慢很多,但是它對硬件的消耗比較少,可以作為一種補充方法。

10.4.2?異常的處理

需要一種方法來記錄所有指令的異常,然后按照指令在程序中原始順序對所有異常進行處理,能夠勝任這個任務的,就是重排序緩存。

為了能夠按照正確的順序處理異常,一條指令的異常要被處理,必須保證在它之前的所有資料的異常都已經被處理完成了,最容易實現這個任務的時間點就是在一條指令將要退休的時候,此時這條指令之前的所有指令都已經順利地離開流水線。

對精確異常處理完后,可以精確地返回,返回的地方可能有兩種情況,可以返回到發生異常的指令本身,重新執行這條指令,也可以不重新執行這條發生異常的指令,而是返回到它的下一條指令開始執行。

在跳轉到相應的異常處理程序之前,需要將流水線中這條產生異常的指令后面的所有指令都抹去,并將它們對處理器狀態的修改進行恢復,就好像這些指令從來沒有發生過一樣。

當一條指令要從ROB中退休之前,如果發現它在之前記錄過異常的發射,此時ROB中所有其實都不允許退休而改變處理器的狀態。

Recovery?at Retire的異常處理方法還有一個好處,那就是很多指令的異常并非真的需要被處理,如果這些指令處于分支預測失敗的路徑上,它們都會從流水線中被抹掉,因此它們的異常其實都是無效的。

另一種修復過程是基于重排序緩存來進行的,從ROB中最新寫入的指令開始,逐個將每條指令對應舊的映射關系寫到重命名映射表中,這樣就可以將這個表格進行狀態恢復了,這個方法就是前文提到的WALK。

在使用統一的PRF進行寄存器重命名的方式中,和RAT相關的內容還有兩個表格,一個表格用來存儲那些物理寄存器是空閑狀態的,稱為Free Register Pool;另一個表格用來存儲每個物理寄存器的值是否已經被計算出來,稱為Busy Table。當異常發生時,這兩個部件也需要進行恢復。

對于異常發生時的處理器來說,如果采用ROB進行重命名架構,使用Recovery?at Retire方式是合適的,而對于采用統一的PRF進行重命名的架構,則需要使用WALK方法。

相比于分支預測失敗,異常發生的頻率會更低。

10.4.3?中斷的處理

在MIPS處理器中,異常是由處理器內部執行指令產生的,因此異常總是和某條指令時同步的;?而中斷指的是處理器外部產生的,它和處理器內部執行的指令沒有必然的對應關系,因此稱中斷是異步的。一般有兩種處理方式:

(1)馬上處理。當中斷發射時,將此時流水線中所有指令都抹掉,對處理器的狀態進行恢復,并將流水線中最舊的那條指令的PC值保存起來,然后跳轉到對應的中斷處理程序,當從其中返回時,會使用中斷發生時所保存的PC值來重新讀取指令。優點在于響應最快,效率較低。

(2)延遲處理。當中斷發生時,流水線停止取指令,但是等到流水線中所有指令退休之后才對這個中斷進行處理。需要考慮的問題:

(a)如果在流水線中的這些指令發生了D-Cache缺失,那么需要很長的耗時間才能夠解決,導致過長的中斷響應時間。

(b)如果在流水線中發現分支預測失敗指令,那么首先需要對這個情況進行處理,將處理器狀態進行恢復,這也需要消耗一定時間,也造成中斷響應時間的增大。

(c)如果在流水線中發現異常,那么先對異常進行處理,還是先對中斷進行處理?一般來說,應該先對中斷進行處理,因為很多類型的異常處理需要很長的時間。

10.4.4?store指令的處理

store指令即使計算完畢,也會將結果暫存在store?buffer,直到store指令退休的時候,才會將store?buffer中對應的內容寫到Cache中。

一旦store指令在寫D-Cache發射miss,則需要等待很長時間才能夠使它離開ROB,這樣就造成了ROB的阻塞,即使store指令有很多指令已經執行完畢,處于complete狀態,但是由于store指令擋在前面而不能退休,造成處理器性能的降低。

解決上述問題最簡單的方法就是在store?buffer中增加一個狀態位,用來標記一條store指令是否已經具備退休的條件,這樣一條store指令在緩存中就有3個狀態,即沒有被執行完畢,已經被執行完畢和順利離開流水線。

當一條store指令在流水線分發階段,按照程序中指定的順序占據store?buffer空間,并被標記未完成。

當store指令成為流水線已經得到地址和數據,但是還沒有變成流水線中最舊的指令,就處于complete狀態。

當store指令成為流水線中最舊的指令并退休的時候,即順利離開流水線狀態。

store指令都是按照程序中指定的順序來執行,當然更需要按照這個順序對處理器的狀態進行更新,所以store?buffer是按照FIFO方式進行管理的。

一旦store?buffer再也找不到可用的空間進行寫入,此時就不能夠接收新的store指令,分發階段之前的流水線就需要暫停。造成store實際可用容量減少。限制處理器性能的提高。

如果不想造成store?buffer實際可用容量的降低,可以將那些已經退休的store指令存儲在一個不同于store?buffer的地方,這個地方可以稱為write?back?buffer,硬件會自動將wirte?back?buffer的store的指令寫到D-Cache中。

?每條store指令一旦退休,就將其從store?buffer寫到write?back?buffer中,也就是說,此時這條store指令可以離開ROB和store?buffer兩個部件。在這個方法中,write?back?buffer已經成為了處理器狀態的一部分。laod指令需要在store?buffer和write?back?buffer兩個緩存中進行查找,這樣增加了設計復雜度。

在進入的同時需要在其中查找有沒有寫到相同的store指令,如果存在,那么就需要將其置為無效,這樣才能夠保證后面的load指令查找write back?buffer,使用最新的結果。

10.4.5?指令離開流水線的限制

如果ROB中最舊的4條指令都已經處于complete狀態,其中沒有發現預測失敗的分支指令,也沒有指令產生異常,那么這4條指令就可以在一個周期內離開流水線?

從理論上說,這4條指令確實可以在一個周期內都退休而離開流水線,但是,這對處理器許多其他的部件提出了更多寫端口的要求 :

(1)每周期有4條store指令,意味著D-Cache后者write?back?huffer需要支持4個寫端口。

(2)每周期4條分支指令退休路,意味著每周期需要將4條分支指令的信息寫回到分支預測器章中,這需要分支預測器中所有部件都需要支持4個寫端口,同時還需要能夠將checkpoint資源在每周期釋放4個。

為這些不經常出現的情況而增加硬件設計的復雜度是得不償失的,因此在超標量處理器中,可以對上述這些特殊的指令進行限制。例如,每周期退休的指令中最多只能有一條分支指令。

在流水線的提交階段需要對指令的異常進行處理,由于需要跳轉到對應的異常處理程序中,所以每周期只能處理一條指令的異常,因此找到第一個產生異常的異常,并將這條指令后面的所有指令都屏蔽,不允許它們在本周期退休。

總結

以上是生活随笔為你收集整理的超标量处理器设计 姚永斌 第10章 指令提交 摘录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。