ARM+s3c2440/s3c2410 学习讨论之2.2.4.1 指令流水线的原理

ARM+s3c2440/s3c2410 学习讨论之2.2.4.1 指令流水线的原理

2009-5-29 16:55:57     收藏  |   打印  |  投票(13)  |   评论(0)  |  阅读 (91611)  ◇字体:[ 大  中  小]

转载请注明: http://blog.mcuol.com/User/fenghua/Article/13185_1.htm

 

2.2.4  指令流水线简介

2.2.4.1 指令流水线的原理

我们知道汽车工厂把汽车加工分成若干阶段,每个阶段由不同的工人或机器来完成一项专门的生产任务,各个阶段构成一条汽车生产线。加工汽车时,为了提高生产效率,不是等一辆汽车加工完后再加工另外一辆汽车(这样势必造成有的工人无活可干,处于等待状态),而是采用流水作业,所有的工人同时工作,同时加工多辆汽车。

微处理器执行指令就像汽车生产线上加工汽车一样,可以把指令的执行分成多个阶段。图2.1显示了一个典型的指令执行过程,在这个过程中把指令的执行分为取指令、指令译码、执行指令三个阶段,在处理器中每个阶段由不同的硬件单元完成。这样执行一条指令至少需要3个时钟周期,如图2.2 显示了处理器执行一条ADD指令的过程。如果处理器采用图2.2的方式方式执行指令,可以看到在执行指令时,微处理器中总有两个硬件单元是空闲的,这是一种浪费。为了充分发挥硬件的性能,提供效率,ARM微处理器执行指令同样采用类似汽车生产线生产汽车的方式,采用流水线方式执行指令,使硬件各个单元并行工作。如图2.3所示,第一个时钟周期微处理器的取指单元取第一条指令ADD;第二个时钟周期微处理器取指单元取第二条指令SUB,译码单元对ADD指令进行译码;第三个时钟周期取指单元取第三条指令CMP,译码单元对第二条指令SUB进行译码,微处理器的执行单元执行第一条指令ADD。以此类推,直到处理器执行完所有指令。采用流水线方式执行指令,充分发挥了微处理器硬件的性能,提高了系统的执行速度。

可见,流水线使得每个时钟周期就可以执行一条指令。随着流水线级数的增加,每一段的工作量减少了,这使得处理器可以工作在更高的频率,进一步提高系统的性能。

2.1 一个典型的指令执行过程

2.2 执行一条ADD指令的过程

2.3  3级流水线示意图

取指:微处理器取指单元从存储器中取得要执行的指令(根据程序计数器),存如指令寄存器。

译码:对指令寄存器中的指令进行分析,确定要进行什么操作。

执行:执行指令规定的操作,并按照指令的要求保存操作结果。

2.2.4.2  ARM的指令流水线

如前所述,ARM7系列处理器采用3级流水线的冯?诺伊曼结构,ARM9系列处理器采用5级流水线哈佛结构,而ARM10则采用6级流水线,ARM11采用了8级流水线。本节将简单介绍一下ARM的3级流水线、5级流水线和6级流水线。

冯·诺依曼结构:是一种将指令存储器和数据存储器合并在一起的存储结构。指令存储器地址和数据存储器地址指向同一个存储器的不同物理位置。因此指令和数据使用同一条数据总线,同一时刻只能取指或取数据。

哈佛结构:是一种将指令存储和数据存储分开的存储结构。指令总线和数据总线分开,可以同时访问,其宽度也可以不同。

           

2.4 冯·诺依曼存储器结构与哈佛存储结构

2.2.4.2.1  3 级流水线 ARM 组织结构
ARM7架构微处理器组织结构如图2.5所示,按处理器核的功能架构可分成数据路径和控制通路。各个部分的功能如下:
1)处理器寄存器堆(Rigister Bank
包括状态寄存器和通用寄存器,主要用来保存处理器的状态和处理器操作需要的数据。它有两个读端口和一个写端口,每个端口都可以访问任意寄存器。另外还有附加的可以访问PC的一个读端口和一个写端口。PC的附加写端口可以在取指地址增加后更新PC,读端口可以在数据地址发出之后从新开始取指。
2)桶形移位器(Barrel Shifter
它可以把指令中的第二个操作数移位或循环移位。
3)运算器(ALU
完成指令集要求的算术或逻辑功能。
4)地址寄存器(Address Register)和增值器(Incrementer
可选择和保存所用的存储器地址并在需要时通过地址增值器产生顺序地址。
5)数据输出寄存器(data-out register)和数据输入寄存器(data-in register
用于保存传输到存储器和从存储器输出的数据。
6)指令译码器和相关的控制逻辑(instruction decode and control)。
完成指令译码和相关的控制逻辑。
ARM7微处理器采用简单的三级流水线架构。如图2.1所示,指令的执行被分为取指、译码、执行三个流水级。各个流水级功能如下:
1)取指(fetch
取指级的任务是从程序存储器中读取指令。
2)译码(decode
译码级完成对指令的分析,并为下一个周期准备数据路径需要的控制信号。在这一级,指令占用译码逻辑,不占用数据通路。
3)执行(excute
完成指令要求的操作,并根据需要将结果写回寄存器。指令占用数据路径,寄存器堆被读取,操作数在桶行移位器中被移位。运算器产生运算结果并回写到目的寄存器中,运算器根据指令需求和运输结果更改状态寄存器的条件位。
 
2.5  3级流水线ARM的组织
对于单周期指令如:ADD R0R1R2,执行时,需要读取两个操作数到A总线和B总线。A总线上的数据来自寄存器(本例中是R1),B总线上的数据可以来寄存器或立即数(本例中是寄存器R2)。B总线上的数据经过桶形移位器移位处理后与A总是上数据在运算器中进行运算,再将结果写回寄存器(本例中是R0),并根据指令要求决定是否更改寄存器堆中的状态寄存器。在指令执行过程中,程序计数器的数据放在地址寄存器中,地址寄存器的数据送入增值器。然后将增值后的数据拷贝到寄存器堆的程序计数器,同时还拷贝到地址寄存器,作为下一次取指的地址。
当处理器执行简单的数据处理指令时,流水线使得平均每个时钟周期能完成1条指令。但1条指令需要3个时钟周期来完成,因此,有3个时钟周期的延时(latency),但吞吐率(throughput)是每个周期一条指令。可以通过下面的指令序列来看看流水线的执行过程。
ADD  R0R1R2
SUB  R1R1R2
CMP  R1R3
流水线指令序列如图2.6所示。
 
2.6 简单指令在流水线上执行过程
在第一个周期,处理器从存储器取出指令ADD;在第二个周期,内核取出指令SUB,同时对ADD译码;在第三个周期,指令SUBADD都沿流水线移动,ADD被执行,而SUB被译码,同时又取出CMP指令。可以看出,三级流水线使得一条指令的执行需要3个时钟周期,但每个时钟周期都可以执行一条指令(吞吐率是每个周期一条指令)。
当执行多周期指令时,流水线的执行不会像图2.6那么规则,图2.7显示了有LDR指令的流水线状态。图2.7中在单周期指令SUB后出现了一条数据加载指令LDR(从存储器加载数据到寄存器)。可以看出LDR要求从存储器中取数据,在周期3执行LDR后,处理器按照LDR指令要求访问存储器(包括给出地址和将数据写会寄存器),即:占用了ARM处理器内部的数据路径。同时译码单元也为下一个周期准备数据路径需要的控制信号。在周期4取指单元、执行单元都需要或准备访问存储器。冯·诺依曼存储结构中指令和数据都存储在相同的存储器中,各个单元不能同时占用冯·诺依曼结构的存储器端口。因此在ARM7指令流水线上必须等LDR指令指令执行完毕后才能恢复正常流水线。这种情况下流水线是不规则的,也不是最佳流水线。我们也看到存储器访问需要花费更多的时钟周期,这也是RISC体系结构要求更多的寄存器的一个原因。
对于LDR这种存储器访问指令,实际是在地址计算时由译码逻辑产生下一周期数据传输所需要的数据路径控制信号。
2.7多周期指令执行流水线
 
根据前面的介绍,ARM处理器中程序计数器PC是取指令的地址,而不是当前正在执行的指令的地址。所以在程序执行当中使用PC的值时,要考虑这个情况。如在图2.7中,当执行ADD指令是,PC的值是LDR指令的地址,因为ARM指令长度是32位的,所以PC的值应该是ADD指令的地址加8个字节。
 
2.2.4.2.2  5 级流水线 ARM 组织结构

为了提高处理器的性能,就要分析影响程序执行时间的因素。计算一个程序执行所需时间的经典公式如下:

公式中:

:表示在程序中执行的ARM指令数;

:表示执行每条指令的平均时钟周期;

:表示处理器的时钟频率。

因为对给定程序(假设使用给定的优化集并用给定的编译器来编译)Ninst是常数,所以仅有两种方法来提高处理器的性能:

(1)提高时钟频率

时钟频率的提高,必然引起指令执行周期的缩短,所以要求简化流水线每一级的逻辑,流水线的级数就要增加。

(2)减少执行每条指令的平均时钟周期数CPI

最理想的情况下CPI等于1,从前面ARM7三级流水线结构中我们看到,多周期指令(访存指令等)会打乱流水线,造成流水线的停顿。

这就要求重新考虑3级流水线ARM中多于1个流水槽指令的实现方法,以便使其占有较少的槽,或者减少因指令相关造成的流水线停顿,也可以将两者结合起来。

3级流水线ARM核在每一个时钟周期都访问存储器,或者取指令,或者传输数据。ARM是冯诺依曼存储结构的,访问数据存储器操作时,不得不停止取指操作,从而使系统性能受到影响。为了改善CPI,存储器系统必须在每个时钟周期中给出多于一个的数据。方法是在每个时钟周期从单个存储器中给出多于32位数据,或者为指令和数据分别设置存储器。

因此,较高性能的ARM核使用了5级流水线,而且具有分开的指令和数据存储器。把指令的执行分割为5部分而不是3部分,这样每个部分的硬件单元的工作减少,为使用更高的时钟频率提供了可能;分开的指令和数据存储器(可能是分开的Cache连接到统一的指令和数据存储器上)使核的CPI明显减少。

在ARM9TDMI中使用了典型的5级流水线。ARM9TDMI的组织结构如图2.8所示。

5级流水线包括下面的流水线级:

(1)取指(fetch)

从存储器中取出指令,并将其放入指令流水线。

(2)译码(decode)

指令被译码,从寄存器堆中读取寄存器操作数。在寄存器堆中有3个操作数读端口,因此大多数ARM指令能在1个周期内读取其操作数。

(3)执行(execute)

将其中一个操作数移位,并在ALU中产生结果。如果指令是Load或Store指令,则在ALU中计算存储器的地址。

(4)缓冲/数据(buffer/data)

如果需要则访问数据存储器,否则ALU只是简单地缓冲一个时钟周期,以便是所有的指令具有同样的流水线流程。

(5)回写(write-back)

将指令的结果回写到寄存器堆,包括任何从寄存器读出的数据。

图2.8显示了5级流水线指令的执行过程。

2.8 五级流水线

在程序执行过程中,PC值是基于3级流水线操作特性的,完全仿真3级流水线的行为。这保证了软件的兼容性,这是十分必要的。

图2.9显示了ARM7的三级流水线和ARM9的5级流水线的对比

 

2.2.4.2.3  影响流水线性能的因素

1)互锁

在典型的程序处理过程中,经常会遇到这样的情形,即一条指令的结果被用做下一条指令的操作数。如图2.10先死了一个互锁的例子。

2.10 5级流水线互锁

2.11 避免互锁

从图2.10可以看出,流水线的操作产生中断,因为第一条指令的结果在第二条指令取数时还没有产生。第二条指令必须停止,直到结果产生为止。图2.11显示了一个可以避免互锁的方法。

2)跳转指令

跳转指令也会破坏流水线的行为。这是因为,当跳转指令被译码时,在它被确认是跳转指令之前,后续的取指操作已经发生。这样一来,已经被预取进入流水线的指令不得不被丢弃。如果跳转目标的计算是在ALU阶段完成的,那么,在得到跳转目标之前已经有两条指令按原有指令流读取。图2.12显示了一个3级流水线的分支跳转执行流程的例子。解决的办法是采用分支预测技术。

2.12 有分支跳转时的流水线

你可能感兴趣的:(arm)