在ARM架构中,流水线技术是实现高性能的关键设计。ARM1156T2-S处理器采用多级流水线架构,大多数数据处理指令都能在单周期内完成,并且支持背靠背执行(back-to-back execution)。这种设计使得处理器能够在理想情况下每个时钟周期完成一条指令的执行,极大提升了指令吞吐量。
但现实情况往往更为复杂。当指令之间存在数据依赖关系时,特别是涉及移位操作或寄存器控制移位的情况,处理器会引入额外的互锁周期(interlock cycles)。这种机制虽然会暂时降低指令级并行度,但确保了程序执行的正确性。
ARM处理器的移位器(Shifter)位于独立的流水线阶段,与算术逻辑单元(ALU)分开。这种设计带来了一个关键特性:当指令需要使用移位器处理某个寄存器时,该寄存器会被标记为"Early寄存器"。
Early寄存器的特点是:它的结果需要比普通寄存器多一个周期的准备时间才能被后续指令使用。这种延迟会导致处理器插入一个互锁周期,表现为指令执行时间的增加。
让我们通过具体代码示例来分析:
assembly复制ADD R1, R2, R3 ; 单周期指令
ADD R4, R5, R1, LSL #1 ; 使用R1作为移位操作数,产生互锁
这个指令序列需要3个周期完成:
有趣的是,如果被移位的寄存器不是数据依赖链的一部分,则不会产生互锁。例如:
assembly复制ADD R1, R2, R3 ; 单周期指令
ADD R4, R1, R9, LSL #1 ; 移位操作使用R9(非依赖链)
这个序列只需2个周期,因为R9不需要等待前一条指令的结果。
当移位操作由寄存器控制时(而非立即数),情况会变得更加复杂。这类指令需要两个周期完成:
由于移位距离寄存器也是Early寄存器,这会引入额外的互锁惩罚。例如:
assembly复制ADD R1, R2, R3
ADD R4, R2, R4, LSL R1 ; R1控制移位距离
这个序列需要4个周期完成,比立即数移位多出一个周期。
特别提示:RRX(带进位循环右移)指令需要提前访问进位标志(Carry Flag),这也会产生类似的互锁行为。在编写涉及条件移位的代码时,需要特别注意这种隐性依赖。
ARM架构提供了一组饱和运算指令(QADD, QDADD, QSUB, QDSUB),这些指令在数字信号处理等场景中非常有用。它们的特殊之处在于结果是在Sat阶段产生的,因此具有固定的2周期结果延迟(result latency)。
更复杂的是QDADD和QDSUB指令,它们需要先对寄存器进行加倍和饱和处理,这个操作发生在流水线的Sh阶段。因此,源寄存器
下表总结了这些指令的周期特性:
| 指令类型 | 执行周期 | Early寄存器 | 结果延迟 |
|---|---|---|---|
| QADD/QSUB | 1 | 无 | 2 |
| QDADD/QDSUB | 1 | 2 |
在编写信号处理算法时,了解这些时序特性至关重要。例如,下面的指令序列:
assembly复制QDADD R1, R2, R3 ; R2是Early寄存器
ADD R4, R1, R5 ; 需要等待R1的结果
由于QDADD的2周期结果延迟,第二条ADD指令必须等待2个周期后才能执行。如果忽略这个延迟,可能会导致性能低于预期。
优化建议:
ARMv6引入了一系列媒体数据处理指令,这些指令在视频编解码、图像处理等领域表现优异。从流水线角度看,这些指令可分为两类:
部分指令需要输入寄存器先进行移位操作,因此被标记为需要Early寄存器。例如SASX、UASX等指令需要
下表展示了部分媒体指令的时序行为:
| 指令组 | 执行周期 | Early寄存器 | 结果延迟 |
|---|---|---|---|
| SADD16/SSUB16 | 1 | 无 | 1 |
| SEL | 1 | 无 | 1 |
| QADD16/QSUB16 | 1 | 无 | 2 |
| SSAT/USAT | 1 | 2 | |
| SXTAB/UXTAB | 1 | 1 |
这类指令在运动估计等算法中非常有用,但有着特殊的行为:
示例序列:
assembly复制USAD8 R1, R2, R3
ADD R5, R6, R1 ; 需要4周期(USAD8延迟3 + ADD执行1)
优化技巧:
ARM1156T2-S的乘法器采用三周期流水线设计,具有以下特点:
乘法指令的延迟差异较大,下表列出典型情况:
| 指令类型 | 执行周期 | 设置标志周期 | Early寄存器 | 结果延迟 |
|---|---|---|---|---|
| MUL(S) | 2 | 5 | 4 | |
| MLA(S) | 2 | 5 | 4 | |
| SMULL(S) | 3 | 6 | 4/5 | |
| SMULxy | 1 | - | 3 | |
| SMMUL | 2 | - | 4 |
注意:当结果用于后续乘累加指令的累加寄存器时,结果延迟会减少1周期。这在设计数字信号处理算法时可以充分利用。
考虑以下序列:
assembly复制SMULL R0, R1, R2, R3 ; 64位乘法
ADDS R4, R0, R5 ; 使用低32位结果
由于SMULL的低32位结果有4周期延迟,ADDS指令需要等待4个周期才能执行。如果忽略这个延迟,会导致读取到错误的数据。
优化建议:
ARM1156T2-S采用两种分支预测机制:
| 分支类型 | 预测情况 | 执行周期 |
|---|---|---|
| B |
预测成功 | 0(被折叠) |
| BL |
预测失败 | 6-8 |
| BX R14 | 预测成功 | 1 |
| BX R14 | 预测失败 | 8 |
| BX |
条件返回 | 6-8 |
基本规则:
关键特性:
行为特点:
通过分析程序中的寄存器依赖关系,找出可能产生互锁的长依赖链。特别是注意:
使用ARM提供的周期精确模拟器或性能分析工具,可以:
在实际嵌入式系统开发中,特别是对实时性要求高的场景,理解这些互锁行为对于写出高性能代码至关重要。通过合理的指令调度和寄存器分配,可以显著减少互锁带来的性能损失。