指令重排令提升程序执行效率提升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

 

 

 

    原文作者:konami
    原文地址: https://www.cnblogs.com/akaneblog/p/11437403.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞