ARM流水线

PC到底是多少呢?

“然后PC=PC+1”,老师经常这么说。

这不完全正确,PC自增一的情况指出现在无流水(non-pipeline)的情况下,这个时候取指,译码,执指都是顺序执行的。而在有流水的情况下就比较复杂了这里用arm7的三级流水线为例。

流水线使用三个阶段,因此指令分为三个阶段执行:1.取指(从存储器装载一条指令);2.译码(识别将要被执行的指令);3.执行(处理指令并将结果写回寄存器)。

而R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令。当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+8;

其余流水线类比此处。

ARM流水线概述

流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一。ARM7处理器核使用了典型三级流水线的冯·诺伊曼结构,ARM9系列则采用了基于五级流水线的哈佛结构。通过增加流水线级数简化了流水线各级的逻辑,进一步提高了处理器的性能。

ARM7的三级流水线在执行单元完成了大量的工作,包括与操作数相关的寄存器和存储器读写操作、ALU操作以及相关器件之间的数据传输。执行单元的工作往往占用多个时钟周期,从而成为系统性能的瓶颈。ARM9采用了更为高效的五级流水线设计,增加了2个功能部件分别访问存储器并写回结果,且将读寄存器的操作转移到译码部件上,使流水线各部件在功能上更平衡;同时其哈佛架构避免了数据访问和取指的总线冲突。

然而不论是三级流水线还是五级流水线,当出现多周期指令、跳转分支指令和中断发生的时候,流水线都会发生阻塞,而且相邻指令之间也可能因为寄存器冲突导致流水线阻塞,降低流水线的效率。本文在对流水线原理及运行情况详细分析的基础上,研究通过调整指令执行序列来提高流水线运行性能的方法。

ARM三级流水线

ARM流水线_第1张图片
ARM7三级流水线结构
ARM流水线_第2张图片
ARM7三级流水线状态


ARM流水线_第3张图片
ARM7三级流水线举例

从上图,其实很容易看出,第一条指令:

add r0, r1,$5

执行的时候,此时PC已经指向第三条指令:

cmp r2,#3

的地址了,所以,是PC=PC+8。

为何ARM9和ARM7一样,也是PC=PC+8?

ARM7的三条流水线,PC=PC+8,很好理解,但是AMR9中,是五级流水线,为何还是PC=PC+8,而不是

PC=PC+(5-1)*4=PC + 16呢?

下面就需要好好解释一番了。

具体解释之前,先贴上ARM7和ARM9的流水线的区别和联系:

ARM流水线_第4张图片
ARM7三级流水线 vs ARM9五级流水线


ARM流水线_第5张图片
ARM7三级流水线到ARM9五级流水线的映射

下面开始对为何ARM9也是PC=PC+8进行解释。

先列出ARM9的五级流水线的示例:


ARM流水线_第6张图片

举例分析为何PC=PC+8

然后我们以下面uboot中的start.S的最开始的汇编代码为例来进行解释:

ARM流水线_第7张图片
start.s

下面对每一个指令周期,CPU做了哪些事情,分别详细进行阐述:

在看下面具体解释之前,有一句话要牢记,那就是:

PC不是指向你正在运行的指令,而是PC始终指向你要取的指令的地址.

认识清楚了这个前提,后面的举例讲解,就容易懂了。

1.指令周期Cycle1

取指

PC总是指向将要读取的指令的地址(即我们常说的,指向下一条指令的地址),而当前PC=4,所以去取物理地址为4对对应的指令.

ldr pc, [pc, #20]

其对应二进制代码为e59ff014。

此处取指完之后,自动更新PC的值,即PC=PC+4(单个指令占4字节,所以加4)=4+4=8

2.指令周期Cycle2

译指

翻译指令e59ff014

同时再去取指

PC总是指向将要读取的指令的地址(即我们常说的,指向下一条指令的地址),而当前PC=8,所以去物理地址为8所对应的指令“ldr pc, [pc, #20]” 其对应二进制代码为e59ff014。

此处取指完之后,自动更新PC的值,即PC=PC+4=8+4=12=0xc

指令周期Cycle3

执行(指令)

执行“e59ff014”,即

ldr pc, [pc, #20]

所对表达的含义,即PC

= PC + 20

= 12 + 20

= 32

= 0x20

此处,只是计算出待会要赋值给PC的值是0x20,这个0x20还只是放在执行单元中内部的缓冲中。

译指

翻译e59ff014

取指

此步骤由于是和上面(1)中的执行同步做的,所以,未受到影响,继续取指,而取指的那一时刻,PC为上一Cycle更新后的值,即PC=0xc,所以是去取物理地址为0xc所对应的指令

ldr pc, [pc, #20]

对应二进制为e59ff014

你可能感兴趣的:(ARM流水线)