William Faulker:「過去永遠不會死,它甚至還沒有過去。」
隨著使用固定長度控制字來操縱亂序執行資料路徑的現代 x86 處理器的出現,RISC 和 CISC 之間的混淆變得越來越嚴重。「RISC 和 CISC 正在融合」是一個在根本上就存在缺陷的觀點,可以追溯到 1992 年 i486 的釋出。其根源在於人們對指令集架構和物理處理器實現細節之間的差異普遍無知。
顯然到目前為止,「RISC」和「CISC」這兩種縮寫術語掩蓋了一個事實,即兩種設計理念都不僅僅處理指令集的簡單性或複雜性...... 從 RISC 和 CISC 的發展史以及兩種方法試圖解決的問題看,這兩個術語都很荒謬…… 關於「RISC 與 CISC」的辯論早已結束,現在必須要進行一個更細緻入微、更有趣的討論,即基於硬體和軟體、ISA 和實現等方面進行討論。
英特爾的 x86 在「引擎的外表」下並沒有 RISC 引擎。它們透過依賴於將 x86 指令對映到機器操作或複雜指令的機器操作序列的解碼 / 執行的方案來實現 x86 指令集架構,然後這些操作透過微架構找到自己的方式,遵守有關資料依賴的各種規則,最終確定時序。
完成這個過程的「微操作」有 100 多位元,攜帶各種複雜特異的資訊,不能由編譯器直接生成,且不一定是單週期。但最重要的是,它們只是一種微架構技巧,而 RISC/CISC 是關於指令集架構的。微操作的想法不是受 RISC 啟發的、「類 RISC」的,或者說與 RISC 完全無關。而是我們的設計團隊找到了一種方法,打破了非常複雜的指令集的複雜性,也擺脫了競爭型微處理器中存在的限制。
我們開發了一個鬆散地基於 29000 指令集的微型 ISA。一些額外的控制欄位將微指令的大小擴充套件到 59 位。其中一些簡化並加速了超標量控制邏輯,其他的用於提供特定於 x86 的功能,這些功能對於效能非常重要,因此不能用微指令序列來合成。但是這些微指令仍然遵循基本的 RISC 原則:簡單的暫存器到暫存器操作,對暫存器指定符和其他欄位進行固定位置編碼,並且每個操作不多於一個記憶體引用。因此我們稱它們為 RISC 操作,或簡稱為 ROPs。這種簡單、通用的特性為實現更復雜的 x86 操作提供了靈活性,從而有利於保持執行邏輯相對簡單。
RISC 微架構最關鍵的一點是 x86 指令集的複雜性止於解碼器,並且在很大程度上對亂序執行核心是透明的。這種方法只需要很少的額外控制複雜度,而不需要亂序的 RISC 執行來實現亂序的 x86 執行。任務切換的 ROP 序列看起來並不比簡單指令串的 ROP 序列複雜。執行核心的複雜性被有效地從架構的複雜性中分離出來,而不是複合起來的。
ISA 並非無關緊要。x86 ISA 非常複雜,因為長期以來人們一直在進行小的更改和補丁,以向 ISA 中新增更多功能,而 ISA 確實已沒有空間容納此類新功能。 複雜的 x86 ISA 使解碼成為瓶頸。x86 指令的長度在 1 到 15 個位元組之間,計算長度非常複雜。在開始解碼下一條指令之前需要知道指令的長度。如果您想每個時鐘週期解碼 4 或 6 條指令,這肯定是個問題!英特爾和 AMD 現在都在不斷增加微操作快取來克服這個瓶頸。而 ARM 有固定大小的指令,所以這個瓶頸不存在,也不需要微操作快取。
x86 的另一個問題是它需要很長的管道來處理複雜性。分支誤預測懲罰等於 pipeline 的長度。因此,他們正在新增越來越複雜的分支預測機制,其中包含大型分支歷史資訊表和分支目標緩衝區。當然,所有這些都需要更多的晶片空間和更多的功耗。 儘管有這些負擔,x86 ISA 還是相當成功的。這是因為它可以為每條指令做更多的工作。