今天寫一個簡短的小話題,內容很少,今天猜一回riscv isa里面定義時一個小點。猜測存在不完全和因果關系錯誤的概率,但去猜測一下不是挺有趣~(評論區更有趣, 有澆CPU的冷水, 還有撒RV圖靈完備+dsa擴展的熱水)
要聊的這個點就是:
riscv的integer instruction set并沒有定義“乘累加”指令,為什么沒有定義?
F/D擴展指令是定義了FMA指令的。
V擴展,也是定義了“乘加指令”。V擴展指令集,要把乘累加相關指令在架構上考慮。如果是發生在占比概率低的指令沒有被基礎指令集定義,是容易理解的。乘累加,應該是V擴展使用概率高的指令。
那么是忘記在integer scalar指令集里定義了嗎? 必然不是。
分析一下對于integer unit,如果定義整數乘加指令,會在微架構設計時,帶來那些改變。
目前可以打敗或者pk一下intel和amd的CPU微架構是什么? 對的,是蘋果的M1 CPU微架構,和arm的V/X系列的CPU微架構。 那么M1和X系列的CPU微架構設計中的定位是什么?
是“kilo instruction processor”,可以接近 “一千條指令量級的 OoO windows”去尋求“推測執行”的微架構。當然對于這樣子的CPU比如高要求帶寬和延時的memory系統和互聯,也是更難的,今天不討論這部分。話說回來,要做到如此高并行度的推測能力的微架構,是“微架構”,“低訪存延時”和“工程實現,工藝”很多因素一起作用。
但是,猜測一下,在riscv isa定義的時候,是否做一些折中,而讓“實現超寬CPU”的一個部件的設計時,相對變得比之前的容易一點,即使設計時做了每條指令3個源操作數有效,對于integer指令部分來講,第3個操作數寄存器實際有效的概率很低。
要實現這個接近千條指令規模的OoO windows,要寬的 decoder 和 rename。同時,不能讓pipeline太長,pipeline越長,對于這個“kilo”大家伙的錯誤penalty就越大, 因為大,所以錯的多,錯的長(latency)也會導致錯誤多。
目前amd商用公布zen最大的dispatch uops能力是8。 arm的x4的每周期的dispatch 最多10 mops或最多20 uops, arm是如何做到每個周期最多10條指令同時完成寄存器重命名的?每條指令有3個源操作數寄存器,那就是30個源操作數寄存器,在一個stage內讀寄存器映射表。當然3個源寄存器操作數有效的,概率是很低的。雖然概率低,但是硬件是現實,依舊要考慮的。微架構設計時是要滿足全部條件的。可以滿足dispatch 10 mops的場景,應該是不多的,可能10個指令里面有一半是只有1個源操作數寄存器有效。
這里arm肯定是在寄存器重命名的前一個stage,完成一些必要的計算,比如每個指令依賴關系,三個源操作數是valid和invalid,同時再細化“合理的利用寄存器重命名表的讀和寫“。

講回來,riscv為這里布局了嗎?為以后的高性能的擴展是不是可能做點折中。
猜測一下,
只有乘加指令是三個源操作數的指令,如果riscv的scalar integer計算指令不定義乘加指令,會讓integer unit的使用”乘“和”加“兩條指令完成等同操作,相對比會是降低??赡軐τ趇nteger unit的性能,乘加指令的被使用的概率和微架構實現是目標折中,只是一個大膽的猜測。
但是,如果設計一個”kilo OoO windows“的riscv cpu,8-width decoder,對于integer unit的所有指令最多只有2個源操作數,來設計微架構時寄存器重命名時,實現上更好一些。
也許這就是riscv在架構定義階段,考慮微架構實現上難度,做了架構定義的結合了integer unit性能,vector unit性能與微架構實現的折中。
如果猜測是對的話,那么”riscv isa是懂微架構的“,對吧。
雖然riscv在integer isa里沒有定義乘加指令,如果真的是為了更寬實現容易實現。那是合理的理由,依舊保持指令集完備性,這也就是一種“合理”。