2 1 5 指令級並行 譯

2022-07-18 09:24:13 字數 3291 閱讀 9573

計算機設計師致力於提公升他們設計的機器的效能。提公升時鐘速度是讓執行晶元更快的一種方法,但是任何新的設計都不得不受限於當時的歷史環境。因此,大部分計算機體系結構在給定時鐘速度的情況下,依靠並行(同時處理兩件或以上的事務)來獲得更多效能。

並行分為指令級並行和處理器級並行兩種。前者的並行指的是運用內部獨立指令來獲取更多的指令輸出。後者的並行指的是多個cpu同時執行來解決相同的問題。兩種方案各有優勢。在本節我們將研究指令級並行;下一節我們研究處理器級並行。

流水線

眾所周知,從記憶體中讀取指令這一過程是影響指令執行速度的一大瓶頸。為了緩和這個問題,老古董ibm stretch(1959)能提前從記憶體中讀取指令,這樣當用到這些指令時,它們已經被讀取過了。這些指令被存在一組特殊的暫存器中,它就是預取緩衝器。這樣,當需要乙個指令時,通常從緩衝器中取出而不是等待記憶體讀取完成。

實際上,預取指令的執行可以分為兩部分:讀取和實際執行。流水線得概念更加深入的執行了這個策略。相比於僅僅被分成兩部分,指令的執行通常被分為許多部分(十幾個或更多),每個部分由專門的一塊硬體處理,所有部分可以並行執行。

圖2-4(a)表示乙個五單元流水線。第一步從記憶體讀取指令,然後把它放入緩衝區直到被取出。第二步對指令解碼,獲取指令型別和它需要的操作子。第三步定位並獲取操作子,每個操作子都是從記憶體或暫存器中讀取。第四步才實際上執行指令,典型的就是通過圖2-2的資料路徑執行運算元。最後的第五步把結果寫回到合適的暫存器中。

在圖2.4(b),我們看到流水線怎樣以函式時間執行。在時鐘迴圈1中,s1正在執行指令1,從記憶體中讀取指令。在迴圈2中,s2對指令1解碼,與此同時s1在讀取指令2。在迴圈3中,s3讀取指令1的運算元,s2解碼指令2,s1請求第三條指令。在迴圈4,s4執行指令1,s3讀取指令2的運算元,s2解碼指令3,s1請求指令4。最後,在迴圈5,s5寫回指令1的結果,同時其他階段執行後面的指令。

為了搞清楚流水線的概念,我們作個模擬。設想乙個蛋糕工廠,對蛋糕的烘焙和打包是分開做的。假設打包部分由5個工人和一條傳送帶完成。每10秒(就是時鐘週期啦),工人1在傳送帶上放置乙個空的蛋糕盒子。盒子被傳送帶送到工人2那裡,工人2網盒子裡放了乙個蛋糕。過一會,盒子送到了工人3那裡,工人3把盒子關上,繫好帶子。然後到工人4在盒子上貼標籤。最後,工人5把蛋糕從傳送帶上拿下來,把它放到了更大的容器裡,這個容器會被送到超市。基本上,這也是計算機流水線的工作方式:每個指令(蛋糕)在完成之前都要經過若干處理步驟。

讓我們回到圖2-4的流水線,假設某台機器的時鐘週期是2納秒。然後一路執行完這個5階段流水線花費10納秒。乍一看,乙個指令花費10納秒,顯得機器可以執行到100mips的樣子,但是實際上它執行的要快得多。在每個時鐘週期(2納秒),乙個新指令就完成了,所以處理過程的實際速度是500mips,不是100mips。

流水線可以在延遲(執行一條指令要花費多長時間)和處理器頻寬(cpu有多少mips)之間做權衡。有乙個時鐘週期為t納秒,階段數為n的流水線,延遲是nt納秒,因為每個指令經過n個階段,每個階段花費t納秒。

由於每個時鐘週期執行一條指令,且每秒有10的9次方/t個時鐘週期,那每秒執行的指令數就是10的9次方/t個。比如說,如果t等於2納秒,那每秒能執行5億條指令。為了獲取mips的數量,我們以百萬為單位來拆分指令的執行率,比如(10的9次方/t)/10的6次方等於1000/t mips。理論上我們可以用bips來代替mips來衡量指令的執行速率,但是沒人那樣幹,所以我們也不會討論了。

超標量結構

乙個流水線已經很好,兩個豈不是更好?有兩個流水線的cpu可能會按照圖2-5來設計。這裡是乙個簡單的指令請求單元,成對的請求指令並把每個指令放到對應的流水線上,連同算術邏輯單元一起做並行操作。為了確保能並行執行,這兩條指令在資源使用(比如暫存器)上不能有衝突,乙個也不能依賴另乙個的結果。正如單個流水線,編譯器要麼必須維持(比如,硬體不會檢查指令的相容性,對不相容的指令會給出錯誤的結果)這種不衝突狀態,要麼能使用額外的硬體檢測並消除衝突。

無論單個還是一對流水線,起初都是用在risc機器上(386和它的前任並沒有),從486開始,英特爾開始在cpu裡引進流水線。486有乙個流水線,最早的奔騰有兩條五階段流水線,和圖2-5相仿,雖然階段2和階段3(稱作解碼1和解碼2)工作內容的準確劃分和我們的例子相比有些許不同。主流水線,也稱作u流水線,可以執行任意的奔騰指令。次流水線,又稱作v流水線,能執行簡單的整數指令(還有乙個簡單的浮點指令fxch)。

由固定規則來判斷一對指令是否互相相容,相容的話可以並行執行。如果這對指令不是足夠簡單或者不能互相相容,那麼只有第一條會被執行(在u流水線)。次流水線上的指令會保留下來,然後和下一條指令結成一對。指令總是按順序執行。因此奔騰特有的編譯器通過生產相容的指令對,可以獲得比老式編譯器更好的執行速度。據度量,執行充分的崩騰處理器的執行速度是相同時鐘週期的486處理器的兩倍(pountain,1993)。這個功勞可以全部算在次流水線頭上。

4流水線齊上不是無法想象的場景,只是這樣做要複製太多的硬體(計算機科學家並不像民間百姓那樣篤信數字3)。在高階cpu上用了替代方法。基本思想是只有一條流水線,但是給它多個功能單元,如圖2-6所示。比如intel core體系有乙個和2-6很相似的結構。我們會在第四章討論該內容。術語超標量體系結構就是為了描述該方法而產生的(agerwala和cocke,1987)。它的根源可以追溯到40年前的cdc 6600。6600每100納秒請求一條指令,然後轉移到10個功能單元中的乙個去並行執行,同時cpu獲取下一條指令。

「超標量」的定義是慢慢形成的。它現在表示處理器能在乙個時鐘週期內能輸出多條指令(通常四或六個)。當然,乙個超標量cpu必須有多個功能單元來處理這些指令。因為超標量處理器通常有乙個流水線,他們看起來像圖2-6。

根據這個定義,6600在技術上並不是超標量的,因為它每個時鐘週期只能輸出一條指令。然而效果是一樣的:指令在以比原本更快的速度執行著。乙個有著100-納秒時鐘,每個週期輸出一條指令給功能單元的的cpu和乙個有著400-納秒時鐘,每個時鐘週期輸出一條指令給功能單元的cpu在概念上的區別是很小的。關鍵點是指令的輸出速率比執行速度要快的多。

超標量處理器思想中隱藏的含義是,s3階段能輸出大量指令,超過了s4階段消化指令的能力。如果s3階段每10納秒輸出一條指令,並且所有的的功能單元都能在10毫秒內完成它們的工作,同一時刻不會有兩個功能單元在忙,那麼整個想法就不能生效了。實際上,大部分位於階段4的功能單元的執行時間都明顯超過乙個時鐘週期,那些讀取記憶體或做浮點計算的功能單元肯定會。如圖所示,階段4可能有多個算術邏輯單元。

8086指令速查

一 資料傳輸指令 它們在存貯器和暫存器 暫存器和輸入輸出埠之間傳送資料.1.通用資料傳送指令.mov 傳送字或位元組.movsx 先符號擴充套件,再傳送.movzx 先零擴充套件,再傳送.push 把字壓入堆疊.pop 把字彈出堆疊.pusha 把ax,cx,dx,bx,sp,bp,si,di依次壓...

11 指令詳解

指令就是一些附加在html元素上的自定義標記 例如 屬性,元素,或css類 它告訴angularjs的html編譯器 compile 在元素上附加某些指定的行為,甚至操作dom 改變dom元素,以及它的各級子節點。通過自定義指令訪問dom 對於angular,乙個程式中唯一允許接觸dom的地方就是 ...

2 指令字首

怎麼判斷是不是字首指令呢?字首指令就幾個,很好確定,根據指令的內容來確定 字首指令最多是4個,每組乙個 1 lock 和repeat字首指令 lock f0 鎖位址匯流排的 在同一時刻只能有乙個核的cpu來讀取那條指令,這個指令在多核下才有意義 repne repnz f2 重複執行 當zf是0的時...