指令重排令提升程序執行效率暴漲20%!


java代碼是否一定按順序執行? 

這個問題聽起來有點蠢,串行的代碼確實會按代碼語意正確的執行,但是編譯器對於代碼本身的優化卻並不一定會按實際的代碼一步一步的執行。

比如:

r1=a;

r2=r1.x;

r3=r1.x;

編譯器則可能會進行優化,將r3=r1.x這條指令替換成r3=r2,這就是指令的重排

編譯器為什么要做指令的重排呢?

地球人都知道,當然是出於性能上的考慮,而指令重排能提升多少性能?

 

首先指令的執行可以分為這幾步:

  • 取指 IF
  • 譯碼和取寄存器操作數 ID
  • 執行或者有效地址計算 EX (ALU邏輯計算單元)
  • 存儲器訪問 MEM
  • 寫回 WB (寄存器)

詳見:https://blog.csdn.net/fuhanghang/article/details/83421254

 

  而一段代碼並不是由單條指令就可以執行完畢的,而是通過流水線來執行多條指令。

流水線技術是一種將指令分解為多步,並讓不同指令的各步操作重疊,從而實現幾條指令並行處理。

指令1    IF    ID    EX  MEN      WB

指令2          IF    ID    EX         MEN      WB

指令的每一步都由不同的硬件完成,假設每一步耗時1ms,執行完一條指令需耗時5ms,

每條指令都按順序執行,那兩條指令則需10ms。

但是通過流水線在指令1剛執行完IF,執行IF的硬件立馬就開始執行指令2的IF,這樣指令2只需要等1ms,兩個指令執行完只需要6ms,效率是不是提升巨大!

 

先記住幾個指令:

MIPS匯編指令集---https://www.cnblogs.com/yanghong-hnu/p/5635245.html

LW(加載數據到寄存器的指令)

ADD(兩個定點寄存器的內容相加)

SUB(相減)

SW(把數據從寄存器存儲到存儲器)

 現在來看一下代碼 A=B+C 是怎么執行的

現有R1,R2,R3三個寄存器,

LW R1,B       IF   ID    EX  MEN  WB(加載B到R1中)

LW R2,C             IF   ID    EX    MEN  WB(加載C到R2中)

ADD R3,R2,R1           IF    ID       ×       EX  MEN       WB(R1,R2相加放到R3)

SW A,R3                           IF      ID     x     EX         MEN      WB(把R3  的值保存到變量A)

在ADD指令執行中有個x,表示中斷、停頓,ADD為什么要在這里停頓一下呢?因為這時C還沒加載到R2中,只能等待,而這個等待使得后邊的所有指令都會停頓一下。

這個停頓可以避免嗎?

當然是可以的,通過指令重排就可以實現,再看一下下面的例子:

要執行

A=B+C;

D=E-F;

通過將D=E-F執行的指令順序提前,從而消除因等待加載完畢的時間。

LW Rb,B       IF   ID    EX  MEN  WB

LW Rc,C             IF   ID    EX  MEN      WB

LW Re,E                   IF    ID    EX  MEN      WB

ADD Ra,Rb,Rc                  IF    ID    EX  MEN      WB

LW Rf,F                                  IF    ID    EX  MEN       WB

SW A,Ra                                         IF    ID    EX  MEN       WB

SUB Rd,Re,Rf                                        IF    ID    EX       MEN      WB

SW D,Rd                                                       IF    ID       EX  MEN      WB

 

 

 


免責聲明!

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



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