处理器流水线第一步是取指。
取指
取指特点:
每条指令在存储器空间所处的地址称为它的PC。 取指是指处理器核将指令从存储器读取出来的过程。按照其指令PC值对应的存储器地址。
取指的目的是以最快的速度且连续不断地从存储器中取出指令供处理器核执行,快和连续不断。
RISC架构汇编指令流特点:
对于非分支跳转指令,处理器需要按顺序执行这些指令,PC值逐条指令增加。处理器在取指的过程中可以按顺序从存储器读取这些指令。
对于分支跳转指令,处理器执行了这条指令后,如果该跳转指令的条件成立,需要发生跳转,则会跳转至另一个不连续的PC值处。
快速取指
为了使处理器核以最快的速度取指,通常使用 指令紧耦合存储器 ITCM和指令缓存。指令紧耦合存储器是指配置一段较小容量的存储器SRAM,用于存储指令,且在物理上离处理器核很近而专属于处理器核。因此能够实现很小的访问延迟。通常一个时钟周期。
ICTM的优点是非常简单,容易理解,且能保证实时性。
ICTM的缺点是由于使用地址区间寻址,因此无法像缓存cache那样映射无限大的存储空间。同时为了保证足够小的访问延迟,无法将容量做到很大,否则无法在一个时钟周期访问SRAM或芯片无法容纳过大的SRAM。因此ITCM只能用于存放容量大小有限的关键指令。
指令缓存是指利用软件程序的时间局部性和空间局部性,将容量巨大的外部指令存储器空间动态映射到容量有限的指令缓存中,将访问指令存储器的平均延迟降低到最低。
由于缓存的容量有限,因此访问缓存存在着相当大的不确定性。一旦缓存不命中,就需要从外部存储器中存取数据,这会造成较长的延迟。在实时性很高的场景中,处理器必须能够实时响应。如果使用了缓存,则无法保证。
大多数低功耗的处理器应用于实时性较高的场景,因此通常使用延迟确定的ITCM。
处理地址不对齐指令
连续不断是处理器取指的一个目标,如果处理器在每一个时钟周期都能够取出一条指令,就可以源源不断地为处理器提供后续指令流。
不管是从指令缓存还是ITCM取指令,若处理器遇到一条指令不对齐的指令,则会给不断取指造成困难,因此ITCM和指令缓存的存储单元往往使用SRAM,而SRAM的读端口有固定宽度,以位宽32位SRAM为例,它在一个时钟周期只能读出一个32位的数据。假设一条32位长的指令处于地址不对齐的位置,这意味着需要分两个时钟周期读出两个32位的数据,然后各取其中一部分拼接成32位指令,这样就需要花费两个时钟周期才能取出一条指令。
对于地址不对齐的指令,对于普通指令和分支跳转指令。
普通指令: 普通指令按顺序取指(地址连续增长),使用剩余缓冲区保存上次取指令没有用完的位,供下次使用。假设从ITCM中取出一个32位的指令字,但是只用了其16位。
是由于只需要此次取出的32位中的低16位和上一次取出的高16位组成一条32位指令。
这条指令的长度本身就是16位,因此只需要取出低16位。 此次没有用到的高16位可以暂时存储在剩余缓冲区,待下一个时钟周期取出下一个32位指令字后,拼接处32位指令字。
分支跳转指令指令不对齐:
如果跳转的目标地址和32位地址不对齐,且需要取出一个32位的指令字,上述剩余缓存就无济于事了。因为剩余缓冲区只有在按顺序取指时候才能预存上次没取完的指令字。常见的方式是使用多体bank化的SRAM进行指令存储。 以常见的奇偶交错方式为例,使用两块32位宽的SRAM交错地进行存储。两个连续的32位指令字分别存储在两块不同的SRAM中,这样对于地址不与32位地址对齐的指令,则在一个时钟周期可以同时访问两块SRAM。取出两个连续的32位指令字。随后各取其一部分拼接成真正需要的32位指令字。
分支指令的处理
无条件跳转指令
带条件跳转指令
为了提高性能,现代处理器的取值单元一般会采用分支预测技术。 对预取的指令进行预测执行。
预测方向:
两位饱和计数器是常见的分支方向动态预测期。
最简单的方式是直接将有限个两位饱和计数器组织成一维的表格,该表格称为预测器表格。并直接使用PC值的一部分进行索引。 例如,若使用PC的后10位作为索引,则需要维护包含1000个表项的表格。
两级预测期,基于相关性的分支预测期,
预测地址:
RISC-V架构对于取指的简化
规整的指令编码格式
指令长度码放于低位
简单的分支跳转指令
没有分支延迟槽指令
提供明确的RAS依据
蜂鸟E203处理器的取值实现
静态预测