指令跳轉與預測


branch指令只有進入decode階段,CPU才能知道是否跳轉。Branch進入到ALU階段,CPU才知道是否taken。

 

有什么方式可以降低這種flush掉沒用的指令。CPU不知道會不會跳轉,以及不知道會跳轉到哪里去。如果在TETCH有可以預測branch是否taken,或者知道taken之后的下一條指令,效率提高。怎么去做到branch。

如何預測?

1.該指令是否是branch指令?

2.判斷是否taken。

3.如果taken,目標地址在哪里?

 

對CPI的影響?

CPI = 1+(mis-predicted/instructions)*penalty

其中penalty就是要Flush掉的指令數量。

下面一個例子:

 

1+0.1×0.2×2=1.04是什么意思?

90%的指令預測准確率,那么有0.1的概率錯誤預測,0.2表示有20%的指令是Branch,2代表有2條指令被Flush掉。

可見在流水線級數很長的情況下,branch的精確度對性能影響非常大。

 

預測branch的思路?

 

一條指令執行的模式是由規律的,這里用到branch的歷史執行方式。

Branch Target Buffer BTB概念,用來存放Branch目標的,當然,已經知道branch是被taken的。Branch目標地址就存放在BTB中,如果該次沒預測對,那么就會更新BTB中的PCnext。如何設計BTB,就是越快越好,那么這個buffer盡可能小。使用PC的低10bit作為BTB的entry。因為正常程序在執行的時候,地址每次加4,也就是只有低bit在改變。

 

簡單的預測banch的方法。1bit 預測。解決branch是否taken。

 

        也就是,現在有條branch指令,走到ALU階段,這條branch被執行了,然而上次branch沒被執行,BHT中存放的是0:Branch is not taken,這是就修改BHT中的值為1:Branch is taken。那么下次在執行Branch的時候,我們預測他會被執行。

1bit預測的優劣。當一條branch總是taken或者taken遠大於不taken,或者正好相反,那么1 bit預測就可以工作很好。但是如果taken 和not kaken次數差不多時候,這個1 bit預測就不管用了。

 

 

2bit 預測,和1bit預測原理差不多,只是多了2種情況。

 

 

   

 

   

一條強烈不執行的branch被taken了,那么就會進入weakly not taken狀態,下次就是直接進入可能不執行的狀態,但是下次真的沒執行,那么就回到強烈不執行狀態;如果被taken了,那么進入到可能執行的狀態。相比於1 bit預測,從not kaken到taken,需要兩次branch taken。

 

從圖中可以看出,當前兩條為NN的時候,那么下一條CPU就預測為Taken;當前兩條為Not Taken和Taken的時候,那么下一條預測為Not Taken。基於歷史來做預測,准確度會更高。

CPU一般是基於2-bits history predict來做的。 

對於函數的返回值指令,如何預測呢?

0x1230: Call FUN
.
.
.
0x1250: Call FUN
 
 
FUN:
     RET 

        PC到0x1230,調用FUN ,FUN執行完后執行RET,回到1230地址,在BTB中更新為1230地址;當程序執行到1250后,有調用FUN,再執行RET,之前BTB已經更新RET為1230,而不是1250,這樣子會導致mis-predict(本應該回到1250),這時BTB會更新到1250;如果程序LOOP到1230,那么每一次branch按照BTB的預測都會失敗。解決這個問題,引入RAS(Return address stack),采用棧的方式解決。執行0x1230的時候,把0x1230push到棧中,RET的時候從棧中取0x1230,當從0x1250調用FUN的時候,把0x1250push到棧中,RET的時候,從棧中調取0x1250。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM