Date: 2018.8.4

-------------------------------------------------------------------------------------------------------------------------​

1、ARM流水线技术

      流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器的效率和吞吐率。ARM7是冯·诺依曼结构,采用了典型的三级流水线,而ARM9则是哈佛结构,采用五级流水线技术,而ARM11则更是使用了7级流水线。通过增加流水线级数,简化了流水线的各级逻辑,进一步提高了处理器的性能。

      在ARM7中,执行单元完成了大量的工作,包括与操作数相关的寄存器和存储器的读写操作、ALU操作和相关器件之间的数据传输,因此占用了多个时钟周期。ARM9增加了两个功能部件,分别访问存储器并写回结果,同时,ARM9将读寄存器的操作转移到译码部件上,使得流水线各部件的功能更平衡。

三级流水线的最佳运行图

【arm】ARM流水线技术与指令使用建议_寄存器


五级流水线的最佳运行图

【arm】ARM流水线技术与指令使用建议_寄存器_02


      在执行的过程中,通过R15寄存器直接访问PC的时候,必须考虑此事流水线执行过程的真实情况。程序计数器R15PC)总是指向取指的指令,而不是指向正在执行的指令或者正在译码的指令。一般情况下,人们总是习惯把正在执行的指令作为参考点,称之为当前第1条指令,因此PC总是指向第3条指令。

对于ARM状态下指令,PC=当前程序执行位置+8;对与Thumb指令,则PC=当前程序执行位置+4.


      三级流水线有它的缺点,当出现多周期指令、跳转分支指令和中断发生的时候,流水线都会发生阻塞,而且相邻指令之间也可能因为寄存器冲突导致流水线阻塞,降低流水线效率。

带分支情况下:

      当指令序列中含有具有分支功能的指令(BL)时,流水线也会被阻断,如图3所示。分支指令在执行时,其后第1条指令被译码,其后第2条指令进行取指,但是这两步操作的指令并不被执行。因为分支指令执行完毕后,程序应该转到跳转的目标地址处执行,因此在流水线上需要丢弃这两条指令,同时程序计数器就会转移到新的位置接着进行取指、译码和执行。此外还有一些特殊的转移指令需要在跳转完成的同时进行写链接寄存器、程序计数寄存器,如BL执行过程中包括两个附加操作——写链接寄存器和调整程序指针。这两个操作仍然占用执行单元,这时处于译码和取指的流水线被阻断了。

中断流水线

      处理器中断的发生具有不确定性,与当前所执行的指令没有任何关系。在中断发生时,处理器总是会执行完当前正被执行的指令,然后去响应中断。如图4所示,在Ox90000处的指令ADD执行期间IRQ中断发生,这时要等待ADD指令执行完毕,IRQ才获得执行单元,处理器开始处理IRQ中断,保存程序返回地址并调整程序指针指向Oxl8内存单元。在Oxl8处有IRO中断向量(也就是跳向IRQ中断服务的指令),接下来执行跳转指令转向中断服务程序,流水线又被阻断,执行0x18处指令的过程同带有分支指令的流水线。


 【arm】ARM流水线技术与指令使用建议_分支指令_03

      五级流水线也有它的缺点,即使存在一种互锁,即寄存器冲突。读寄存器是在译码阶段,写寄存器是在回写阶段。如果当前指令(A)的目的操作数寄存器和下一条指令(B)的源操作数寄存器一致,B指令就需要等A回写之后才能译码。这就是五级流水线中的寄存器冲突。

虽然流水线互锁会增加代码执行时间,但是为初期的设计者提供了巨大的方便,可以不必考虑使用的寄存器会不会造成冲突;而且编译器以及汇编程序员可以通过重新设计代码的顺序或者其他方法来减少互锁的数量。另外分支指令和中断的发生仍然会阻断五级流水线。

 2、ARM指令使用建议

根据ARM流水线原理,

流水线只有被指令填满时才能发挥最大效能,即每个时钟周期完成一条指令的执行(仅单周期指令)。ARM指令大部分都是单周期指令。但是,如果程序发生跳转(B指令或者BL指令),流水线会被清空,在执行B指令之后,后面的取指和译码操作就会被中断,这将需要几个时钟才能使流水线被再次填满。因此,尽量地少使用跳转指令可以提高程序的执行效率。

具体arm neon优化技巧可以参看:​​​

---------------------------------------------------------------------------THE END-----------------------------------------------------------------------------