在CPUCore中,一条存储器指令首先经过取值,译码,Dispatch等一系列操作后,率先到达LSU(Load/Store Unit)部件。LSU部件可以理解为存储器子系统的最高层,在该部件中包含Load Queue与Store Queue。其中Load Queue与Store Queue之间有着强烈的耦合关系,因此许多处理器系统将其合称为LSQ。在多数处理器的存储器子系统中,LSU是最顶层,也是指令流水线与Cache流水线的联系点。
LSU部件是指令流水线的一个执行部件,其上接收来自CPU的存储器指令,其下连接着存储器子系统。其主要功能是将来自CPU的存储器请求发送到存储器子系统,并处理其下存储器子系统的应答数据和消息。在许多微架构中,引入了AGU计算有效地址以加速存储器指令的执行,使用ALU的部分流水处理LSU中的数据。而从逻辑功能上看,AGU和ALU所做的工作依然属于LSU。
在一个现代处理器系统中,LSU部件实现的功能较为类同。LSU部件首先要根据处理器系统要求的Memory Consistency模型确定Ordering,如果前一条尚未执行完毕存储器指令与当前指令间存在Ordering的依赖关系,当前指令不得被Schedule,此时将Stall指令流水线,从来带来较为严重的系统惩罚;LSU需要处理存储器指令间的依赖关系,如对同一个物理地址的多次读写访问,并针对这种Race Condition进行特殊优化;LSU需要准备Cache Hierarchy使用的地址,包括有效地址的计算和虚实地址转换,最终将地址按照L1 Cache的要求将其分别送入到Tag和状态阵列。
L1 Cache层面需要区分是存储器读和存储器写指令。无论是存储器读还是写指令穿越LSU部件的过程均较为复杂。为缩短篇幅,下文重点关注存储器读指令的执行。存储器读操作获得物理地址后将进行Cache Block的状态检查,是Miss还是Hit,如果Cache Hit,则进行数据访问,在获得所需数据后更新在LSU中的状态信息。
如果在L1Cache中Miss,情况略微复杂一些。在现代处理器系统中,Non-Blocking Cache基本上是一个常识般的需求,为此首先需要在MSHR中分配空余Entry,之后通过L1 Cache Controller向其下Memory Hierarchy发送Probe请求。
在L1 CacheController中,大多使用Split Transaction发送这个Probe请求,之后经过一系列复杂的操作,这个操作涉及多核之间的Cache一致性,不同的一致性协议对此的处理不尽相同。在获取最终数据之后,回送Reply消息。LSU在收到这个Reply消息后将数据传递给指令流水线,并释放MSHR中的对应Entry。
以上这些操作可以并行执行,如使用VirtualCache方式可以直接使用虚拟地址,而无需进行虚实地址转换,可以将数据访问与Tag译码部件重叠,更有一系列预测机制进一步缩短数据Cache访问的延时。
存储器写的过程较存储器读复杂一些,在L1Cache Hit时,会因为状态位的迁移而带来一系列的Bus Traffic;如果在L1