RISC-V 不定長的指令週期

現代CPU由於存在多級流水線,對於分支處理又存在分支預測功能,因此在實際cpu的運行過程中,beq指令的週期不是固定的。
另外,即使對於其他指令,比如lw指令,其指令週期也不是固定的。取決於該指令跟後面的指令有沒有依賴關係。在這裏插入圖片描述 使用2週期的那些lw指令的bne指令都是需要用到前一條lw指令的結果,所以必須等前一條完成之後才能執行。比如 lw a0,1540(t1)與bne a0,x0,-1,bne指令必須等 a0 的 load 結果出來之後才能開始執行。lw 本身都是4週期的,如果前後沒有依賴關係就可以pipeline起來,看起來就是一個週期完成一樣。比如圖中前面那些1個週期的lw指令都是沒有依賴關係的。另外,lw 週期數跟具體實現有關係,最少2週期,如果存儲接口插入了等待週期會更長,具體到某個指令多少得分析微架構。所以說,並不能直接從代碼段知道一個函數的實際運行時間,需要實際運行看看。
執行一個小程序進行測試(測試cpu爲8級流水線),從log中獲知一共使用了31個不同的指令。指令和指令次數爲:
在這裏插入圖片描述

1, 跳轉和返回指令

jal指令:

即使沒有依賴關係,也是最少5週期:本測試一共有2983個jal指令,其指令週期和次數有:
在這裏插入圖片描述
可以看出,jalr指令的大部分的指令週期是5。

jalr指令:

jalr指令一共有2279個jalr指令,其指令週期和次數有:
在這裏插入圖片描述
可以看出,jalr指令的大部分的指令週期是5。

mret指令

mret指令,一共79個:
在這裏插入圖片描述
大部分爲9個週期。

2, add和addi指令

add指令,一共4129個,1個週期和4個週期大約各佔一半。
addi指令,一共22708個,大部分是1個週期。
僞代碼中的li指令,會轉換爲addi指令來執行。比如li a5,4指令,會轉換爲addr a5,x0,4。

3, load和store指令

在這裏插入圖片描述

lw指令

lw指令,一共24338個,1個週期和2個週期的大約各佔一半。
在這裏插入圖片描述

lbu指令

lbu指令,一共1572個:
在這裏插入圖片描述
可以看出,lbu指令的時間週期並沒有比lw指令少。

sw指令

sw指令,一共13636個,大部分需要1個時鐘週期。
在這裏插入圖片描述

sb和sh指令

sb和sh指令與sw指令類似,大部分需要1個時鐘週期。

4,分支預測指令

在這裏插入圖片描述

bne指令

bne指令,一共5389個:
在這裏插入圖片描述
66%是7個週期。
有1次15 cycle是因爲後面來了一箇中斷,需要跳轉到中斷服務函數。
有11次用了13個cycle, 主要就是分支開銷, 沒有指令預測, 結果遇到分支跳轉,開銷就大;一般跳轉後面的時間長, 很大可能都是分支跳轉的開銷。開銷最大的情況是跳轉後 又遇到 cache miss; 計算這個開銷是 從取指令到提交的流水線級數+cache miss的取指時間。
總結:所以我們在寫代碼的時候,最好把運行概率大的那個分支寫到if中。

bge,begu,blt指令

這三個指令大部分都是6個週期。可以看到,分支跳轉指令是比較耗時的。

5, 與狀態寄存器有關的指令

csrrs,csrrw,csrrwi,這些指令在實際測試中一般耗費4個時鐘週期。

6,nop指令

nop指令,一共1060個:
在這裏插入圖片描述

7,其他指令

大部分都是1個時鐘週期。

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