X86處理器架構--Nehalem

處理器發展歷史

最開始的處理器比較簡單,8086處理器是評估當前的指令指針(CS:IP)指向的指令,然後再執行解碼、執行、退出,並移動指令指針到下一個位置,每一個新的芯片都做了改進,大多數的芯片增加了新的功能,一些增加了新的寄存器,基於本篇文章的目的,我主要關注在對指令集運行方面有很大影響的變化,其它的例如新增了虛擬內存空間或者平行處理器等也非常值得一說和有用,但是這篇文章不會討論。

指令集緩存在1982年被加入到CPU中,取代了每次執行一個指令都要去訪問主內存,CPU只要讀取當前指令指針指向的數據即可,但是指令集緩存很小,僅僅可以緩存很少的指令,但是確實通過減少了來回訪問主內存的次數提高了性能。

1985年,386新增了數據緩存,同時擴展了指令集緩存,通過讀取數據之外的層面提高了性能,在這點上指令集緩存和數據緩存大大小也從幾個字節上升到幾千的字節層面。

1989年,i486升級到了5層流水線,相對於以前每個CPU只有一個指令處理的流水線,現在每一層都有一個指令處理流水線,在相同的時鐘頻率下,486的性能是386的2倍,每一個流水線都從緩存中獲取指令(當時的指令集緩存大部分都是8KB),第2層的流水線會解碼指令集,3層會解析指令執行需要的內存地址(要理解這一點需要明白計算機中的內存地址表示方式),第4層會執行指令,第5層執行退出,如果需要的話把結果寫回到寄存器和主內存。在CPU可以一次處理多個指令之後,程序可以運行的更快了。

1993年,奔騰處理器誕生,由於法律訴訟原因處理器的名字由數字被變爲名稱,這就是爲什麼叫奔騰而不叫586的原因,奔騰架構新增了一個二級獨立超大流水線,主流水線和i486類似,但是二級流水線執行一些簡單指令,例如整數的運算,並行並且變得更快了。

1995年,Intel發佈了奔騰專業版,這是一個完全不同的處理器設計,這個芯片有幾個最新的特性包括無序執行核心(OOOcore)和隨機執行,流水線被擴展到了12層,它包括一個叫做超級流水線的東西,許多指令可以被並行同時處理,這個OOO核心我們後面會深入討論一下。在1995年OOO被引進到2002年我們的下一個階段出現之間,有很多變化,新增了額外的寄存器,一條指令處理多條數據(單指令多數據或者叫SIMD),緩存被不斷添加,已有的緩存被不斷增大,流水線有時被拆分了有時被固定,這些改變對性能翻倍提升都特別重要,但是這些改變對於通過芯片的數據流的改變都不大(這塊不太理解)。

2002年,奔騰4核心處理器引入了一項新的技術:”超線程“,OOO核心在提升CPU處理指令流的方面太成功了以至於處理的速度要比指令發送給核心的速度還要快,甚至在(高)負載的情況下,對於大多數的用戶來說OOO核心因爲效率太高了所以大部分時間都是空閒,爲了更穩定和高效的給OOO核心發送指令,他們設計了第2層的front-end,操作系統會識別到2個CPU,有2組的寄存器,有2組的指令集解碼器在遍歷指令集指針和處理結果(相當於要加速給核心發送指令集的速度),結果集被一個共享的OOO核心處理,但是這個過程應用程序是不知道的,然後指令就像以前那樣執行退出,結果被髮送給他們來的那個對應的核心。(這裏翻譯的不好,大家有時間可以看看原文。)

2006年,Intel發佈了微核心架構,更長遠來看,它被稱爲“core 2”(因爲人們知道core2 肯定比core1要好),有一個讓人驚訝的改動,CPU的時鐘頻率被降低了,超線程也被移除了,通過降低時鐘頻率,Intel纔可以擴展了所有的流水線平臺,OOO核心被擴展了,緩存和緩衝區被加大了,處理器被重新設計成爲專注於具有共享高速緩存的雙核和四核芯片。

2008年,Intel發佈了一系列的酷睿i3、i5和i7處理器,被設計成爲重新引入了帶有共享OOO核心的超線程處理器,這3款處理器最大的區別就是內部的緩存大小不一樣。

未來的處理器,下一代的微架構處理器更新現在叫做HasWell,大概會在2013年發佈,到目前爲止公佈的文檔顯示這款處理器採用了14-stage的OOO核心流水線,所以數據流的設計很可能仍然在遵循奔騰專業的設計

Intel Nehalem是Intel研發的中央處理器微架構之代號,該架構取代了前代的Core微處理器架構。使用Nehalem架構的微處理器採用45納米 製程(後期改用32納米制程),在2007年的Intel開發者論壇上Intel官方展示了一個採用兩顆INehalem微架構的處理器的系統平臺。首款採用Intel Nehalem架構的處理器是2008年11月正式發售的桌面型處理器Intel Core i7 。

Inter Core i7架構

目前Inter Core i7使用Nehalem微架構來實現CPU內部結構,而ARM微架構依然沿用Cortex。

Nehalem是一款OOO(Out of Order)亂序執行的Superscaler(超標量)的X86處理器。

超標量意味着CPU中有多個執行單元,可以在同一時刻執行多條無相關依賴性的指令,從而達到提升ILP(Instruction Level Parallelism)指令並行化的目的。

亂序執行則是指在多個執行單元的超標量設計中,一系列的執行單元可以同時運行一些沒有數據以及邏輯關聯的若干指令,只有需要等待其他指令運算結果的數據會依照順序執行,從而提升執行效率。

Intel Nehalem arch

Inter Core i5

CPU PipeLine執行流程

取指與解碼(Front-End In-Order)

  • Instruction Fetch:將主存中的指令集合(4K左右)加載到L1的Instruction Cache中
  • Prefetch Buffer:從L1的指令緩存裝載16Byte長度的指令到Buffer
  • Predecode&Instruction Length Decoder:將上過程中Buffer的指令進行指令長度解析(確定指令長度,解碼指令前綴,爲解碼器標註指令類型等)以及進行分支預測的處理(確定分支指令的的跳轉,使用BTB保存分支預測指令的地址)避免處理器在執行預測路徑上的時候不會'"stalling"

由於X86是CISC指令集的處理器,CISC的指令是變長指令集,所以在解碼之前,需要將指令進行解析,確定指令的前綴、長度等等,而RISC指令集則不需要進行該處理,因爲RISC是等長指令集。

  • Instruction Queue:將Predecode處理過後的指令進行指令對齊以及宏指令的融合(將可融合的指令送到解碼器,生成新的指令,如比較判的分支X86指令集最終解碼成單條micro Op,從而提升解碼器的帶寬,降低指令數量,提高運行效率)
  • Complex&Simple Decorder:將Instruction Queue中的指令進行解析,Complex Decoder負責解碼複雜指令,將單條複雜的x86指令翻譯成1-4條Micro Ops,Simple Decoder負責解碼簡單指令,將單條簡單的x86指令翻譯成1條類RISC指令的Micro Op

X86的CPU屬於CISC指令集,由於CISC的指令長度不固定,而且執行時間也不固定,所以Nehalem架構會將CISC指令通過Predecode以及Decode處理成類RISC指令(也就是Decode完的MicroOp),因爲RISC指令長度等長,執行時間恆定,通常一個cycle就能執行完,因此後續處理器設計就會比較簡單,並且流水線的長度可以達到很長,使得CPU可以到達很高的頻率。

  • Decoded Instruction Queue:接收到了解碼後的Micro Ops後,會經過Loop Stream Decoder以及Micro Instruction Sequencer

Loop Stream Decoder會對循環段(如for,while,do...while)少於28個ops的情況下,會保存起來,而不需要再重新取指,進行分支預測以及解碼等操作,並且Instruction Sequencer會將指令進行序列化

  • MicroOp Fusion:將多條Micro Ops進行融合,用於降低Micro Ops的數量,提高指令執行的吞吐量,以及Reorder Buffer的使用效率

執行引擎(Out-Of-Order Executor)

OOOE是爲了直接提升ILP(Instruction Level Parallelism)指令集並行化的設計,在多個執行單元的超標量設計中,一系列執行單元可以同時執行一些沒有數據關聯性的若干指令,只有需要等待其他指令運算結果的數據會按照順序執行。

  • 2 x Register Allocation Table:不同的指令可能都會需要用到相同的通用寄存器(GPR,General Purpose Registers),爲了在這種情衝突的況下指令們也能並行工作,處理器需要準備解決方法。一般的RISC架構準備了大量的GPR,而x86架構天生就缺乏GPR(x86具有8個GPR,x86-64具有16個,一般RISC具有32個,IA64則具有128個),爲此Intel開始引入重命名寄存器(Rename Register),不同的指令可以通過具有名字相同但實際不同的寄存器來解決(爲了SMT同步多線程,這些寄存器還要準備雙份,每個線程具有獨立的一份)

寄存器重命名避免了機器指令或者微操作不必要的順序化執行,從而提高了處理器的指令級並行的能力。

  • ReOrder Buffer:只能存放128條指令,將寄存器重命名後的指令按照編程的原始順序重新排序成一個隊列,把打亂了次序的指令們依次插入隊列中。
  • Reservation Station:指令保留站,等待源數據到來,以進行OOOE亂序執行,而沒有數據的指令,則在Reservation Station中等待,直到等待到了數據後,通過各個端口發送到ALU中進行運算和執行,最終將運算數據通過MOB存入L1的數據緩存中,並且將結果通過Result Bus分發到ROB中,如果運算已經完成,則會更新ROB中的指令結果,並且從ROB中移除已經完成的指令,將該指令放到RRF中。除了存放指令之外,保留站的作用是監聽內部結果總線上是否有保留站內指令所需要的參數。需要讀取L1/L2緩存乃至內存的指令或者需要等待其他指令結果的指令必須在此等待
  • Retirement Register File:從ROB中移出一條指令就意味着指令執行完畢了,這個階段叫做Retire回退,相應地ROB往往也叫做Retirement Unit(回退單元),並將其畫爲流水線的最後一部分。該部件存儲了被提交的體系寄存器的狀態,通過邏輯寄存器的號來查詢這個寄存器堆,用於進行寄存器是否可用的標識,爲寄存器重命名查詢寄存器狀態以便提供空閒寄存器。

重要部件

CPU中分爲以下重要的部件:

  • PipeLine
  • 超標量&超線程
  • Hardware Prefetch:根據歷史操作預先加載以後會用到的指令來提高性能
  • 分支預測(Branch Prediction)
  • Macro Ops && Micro Ops指令融合(MicroOp Fusion)
  • LSD
  • Register Allocation Table
  • ROB
  • RRF
  • MOB
  • Cache:L1,L2,L3緩存
    • L1:分爲指令緩存(Instruction Cache,32K)以及數據緩存(Data Cache,32K):(N路集合關聯)
    • L2:每個核超線程共享一個256K緩存(N路組相連(N Way Set-Associative))等
    • L3:所有核共用同一個8M的緩存
  • 多核CPU的總線:QPI

參考資料

http://blog.jobbole.com/40844/ https://commons.wikimedia.org/wiki/File:Intel_Nehalem_arch.svg http://wsfdl.com/linux/2016/06/11/%E7%90%86%E8%A7%A3CPU%E7%9A%84cache.html http://igoro.com/archive/gallery-of-processor-cache-effects/ http://cyningsun.github.io/06-01-2016/nehalem-arch.html https://classroom.udacity.com/courses/ud007/lessons/fecc80f7-8a59-4708-af48-80d2c6453747/concepts/c71890f8-b128-4c5d-86dd-a704e99e09af https://compas.cs.stonybrook.edu/~nhonarmand/courses/sp15/cse502/slides/12-inst_flow.pdf http://test.m.it168.com/article_369202.html http://server.it168.com/a2008/1224/261/000000261184_3.shtml Inside Nehalem: Intel’s Future Processor and System

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章