為什麼 ARM 和 MIPS 那麼多寄存器,x86 那麼少?
這與RISC更節省晶體管有關嗎?
另外,RISC寄存器多是否是很大優勢?x86的寄存器數量是否成為它的瓶頸?
謝邀。
通用寄存器數目的多少是由ISA決定的,指令編碼時會單獨給寄存器欄位進行編碼,比如5bits就可以索引2^5=32個通用寄存器,一條指令的長度是有限的,指令類型,源操作數欄位、目的操作數欄位,可能的狀態位欄位(比如謂詞寄存器等)以及立即數欄位都需要一些bits來編碼,所以相互之間存在競爭關係,如果寄存器太多,一條指令上能攜帶的操作數種類和數量就會受限,這裡需要一個精巧的權衡。
x86一開始並沒有使用太多的通用寄存器,原因之一(注意,只是之一)是當時的編譯器無力進行寄存器分配,讓編譯器自動決定程序中眾多變數哪些應該裝入寄存器哪些應該換出、哪些變數應該映射到同一個寄存器上,並不是一件易事,JVM採用堆棧結構的原因之一就是不信任編譯器的寄存器分配能力,轉而使用堆棧結構,躲開寄存器分配的難題。
到80年代早期,IBM的G. J. Chaitin公開了他們的圖染色寄存器分配演算法之後,編譯器的分配能力獲得長足進步,形成了現在這樣的編譯器主導的寄存器分配格局,這個寄存器分配演算法是IBM內部進行的一個RISC早期試驗項目的一部分,但是我並沒有看到有公開資料表明他們當時已經意識到RISC的寄存器數目將帶來的性能暗示,而在圖著色演算法走向公開、成熟之前,RISC的理念就已經定型了,所以我也不認為RISC構建過程中有非常注重寄存器數目的考量,寄存器數目只是RISC發展中一個有意無意的副產品。當時RISC的主力推手之一,我們這個領域的泰山北斗David Patterson與DEC VAX團隊的兩位架構師Douglas W. Clark and William D. Strecker在《體系結構通訊》(CAN)上刊文論戰時也並未以寄存器數目優勢來說事。(推薦拙作一篇,RISC誕生與發展的縮影)
【2015.03.11修正:我看到G. J. Chaitin在1980年發在Computer Languages上的圖染色寄存器分配論文裡面寫道他們儘力爭取有更多的計算分配到通用寄存器上來,並且和當時其他的編譯器做法不同,他們儘力不去把寄存器交付給專門用途,而是選擇把盡量多的寄存器合併成一個池子,由此推論,我相信他們當時已經非常清醒地意識到了通用寄存器數目的價值。】
而到了90年代初期,在RISC論戰中敗下陣來的Douglas W. Clark又在體系結構領域的頂級會議ASPLOS刊文分析RISC和CISC的優劣(Performance from architecture: comparing a RISC and a CISC with similar hardware organization),這一回他筆鋒一轉大唱RISC讚歌,從他的行文來看,寄存器數目優勢對性能的幫助似乎已經成為當年的學術共識。。。。。
到了今天,又是另一番光景。通用寄存器數目的多少不再對性能有太大影響,原因是微結構的發展將ISA層面的影響逐步抹平,比如寄存器重命名,memory disambiguation這些技術都能幫助x86部分緩解、掩蓋寄存器數目不足的問題。所以RISC寄存器多也不能獲取多大優勢,x86也並不會因此落後,關鍵還是要看微結構、以及更底層的電路器件工藝實現。
寄存器數目與晶體管數目沒有什麼關聯。
補充:我遇到一些沒有理清概念的人認為寄存器重命名可以完全補足甚至顛覆ISA可見寄存器數目不足的問題,這是不對的。寄存器重命名只能緩解這個問題。重命名可用的物理寄存器再多,地位也與ISA可見的寄存器是不同的。
最大的區別是ISA可見的寄存器有助於削減register spilling時的load store,而物理寄存器對此沒有任何幫助,是的,沒有任何幫助。可供重命名的物理寄存器數目增多以後,register spilling帶來的load store仍可能居高不下,這個簍子得靠memory disambiguation來彌補,更準確地說是reg-mem-reg的數據前遞(bypass)x86那麼多種定址模式,當年如果通用寄存器很多的話,對於地址解碼器來說實在是有點災。
x64的時候amd並沒有選擇特別激進,只把通用寄存器翻了1倍,ip寄存器變成可以定址,,,然而這廝實在陰險,大幅度增加了SSE部分的寄存器數量:因為老x86指令集的專利快到期了,怎麼構築intelamd在市面上吃獨食的防火牆? 大力推銷SSE2之後加的一堆寄存器進入x64 ABI標準。。。
不過有生之年應該很難見到x128的出現吧,我覺得允許使用超過16位元組長度的指令(也允許訪問更多通用寄存器)的併兼容x86和x64的cpu應該會是x64的下一代產品。
指令集ISA決定編譯器可以看到的寄存器,實際晶元微架構實現時,為解除寄存器相關依賴,開發指令集並行,從而超標量多發射亂序執行得到更高的性能,會寄存器重命名擴展更多的物理寄存器。當然現在也有一些CPU,例如TENSILICA,有寄存滑窗,各種調用時可以指定窗口,這樣也擴展了實際寄存器數量。
為了兼容古董程序。寄存器多了命名也要多,名字多了占的地址空間多,太多了指令集就要改,改了就沒法兼容40年前的程序,於是只能這樣了。
x86一開始並沒有使用太多的通用寄存器,原因之一(注意,只是之一)
補充 @迪迦奧特曼
寄存器工藝正向推動。因為那時候寄存器貴。硅工藝逆向推動。因為那時候處理器不比內存快,直接從內存取數據在進行操作也沒什麼。寄存器越來越便宜,剪刀差越來越大,然後ISA中的指令類型也發生變化,0,1,2,3地址指令。如有錯誤歡迎指正。
x86 x64可以玩寄存器重命名,實際的寄存器數量不見得少多少。
現代的x86處理器吃進CISC指令,轉換成類似RISC的微指令【micro-ops】,交給後面的類RISC核心去執行。
這樣一來,RISC核可以做的事情X86核也能做。
不過還是有點硬傷:
1. 對於編譯器和程序來說,並不能看到這些藏在寄存器重命名機制底下的多出來的寄存器。結果就是x86系沒辦法使用一個很高級的功能: 通過編譯器在編譯時而非運行時優化指令調度,盡量讓指令塞滿cpu流水線從而提高執行效率。2. 同上的原因,x86系寄存器少,騰挪的空間不如RISC系,難以利用寄存器之間的操作減少對內存的訪問而提高性能。回到問題,ARM和MIPS們的寄存器多,X86 X64的寄存器少,確實是RISC的優勢。
但是這點不同從目前的情況來看不是決定CPU性能的主要因素。
主要原因是:上述的1.在教科書上工作得很好,nb的編譯器配合一個簡單的低功耗的順序執行核心,一樣可以把指令調度好,流水線效率很高。而現實世界中是亂序執行+分支預測+寄存器重命名的架構做得更好。最近一個比較強大的順序執行核心應該是power6,它的後代又轉向亂序了。32-bit ARM 和 x86-64 的通用寄存器一樣多,都是 16 個。實際能用的寄存器 ARM 可能還要少一兩個。
推薦閱讀:
※如何評價驍龍808?
※CPU 違反能量守恆定律嗎?
※地平線/深鑒科技/寒武紀有什麼異同?
※至強E3 1231 v3和i5 6500誰的性價比高?
※如何看待最近AMD的演示上Ryzen 3.4Ghz主頻渲染時間 36秒 ,小勝6900K?