4.2 存储器读写指令的发射与执行2

来源:互联网 发布:柏曼灯具怎么样知乎 编辑:程序博客网 时间:2024/06/08 03:23

x86处理器系统中,存储器指令大体可以分为F(reg, reg)[1]F(reg, mem)F(mem, reg)三大类。在这些指令中,第1Operand为目标操作数也可以为源操作数,第2Operand只能为源操作数。与LSU部件直接相关的指令为F(reg, mem)F(mem, reg)。后一类指令的处理相对较为复杂,该类指令需要首先进行存储器读,进行某种运算后,再次进行存储器写,即Read-Modify-Write μop。在Opteron微架构中,浮点和SSE指令的存储器读写依然需要通过Integer指令流水,为简化起见,下文不再讨论浮点和SSE指令的存储器读写指令。

一条存储器指令的执行需要使用AGUALULSU三大部件。AGUALU将和LSU部件协调流水作业,最终完成一次存储器读写操作。L1 CacheLoad-Use Latency参数的计算是从存储器指令进入LSQ开始计算。为了实现指令流水的并发高速运转,在AGUALU中也具备多级流水结构。存储器指令在通过ALUAGULSU部件的过程中存在相互依赖关系,如43所示。

4.2 <wbr>存储器读写指令的发射与执行2

我们分别讨论F(reg,mem)指令和F(mem, reg)指令的执行过程。在RS(Reservation Station)等待的F(reg, mem)指令,当所需的Operands Available后首先LaunchAGU部件,并在地址计算完毕后,将结果发送到LSU部件。但是存储器访问μop是同时进入到AGULSU部分中的,只有LSU需要等待AGU的计算结果。

LSU部件从存储器子系统中获得最终数据之后,将其送给ALU,并最终完成指令的执行。F(mem, reg)指令的执行过程与此相近,只是需要在LSQ中经历两次等待过程,第1次是等待ALU计算的结果,第2次等待Store μopcommit将结果最终写入CacheF(mem, reg)进行存储器读时的操作与F(reg, mem)一致。

AGUALU Pipeline的执行过程较易理解,本篇对此不做进一步的说明。Opteron LSU的设计使用TagData总线分离的方式。Scheduler在监听Result Bus时,发现对应的Tag有效时即可启动LSUALUμop,不必等待Data总线,通常情况下Tag bus上的数据先于Result Bus一个cycle,以Overlap不同的流水阶段。在Opteron微架构中,1Cycle,可以Launch一个ALU和一个AGU微操作。如43所示,这两个操作显然没有对应关系。

LSU部件负责与其下的存储器子系统进行数据交互,也是43所示三大部件中最为复杂的一个部件。在Opteron微架构中,LSU由两个部件组成,分别是LS1LS2。其中LS1中含有12EntryLS2中含有32Entry,共44Entry[6]

LS1LS2也被分别称为Pre-CachePost-Cache Load/Store Unit,绝大多人会认为LS1用于访问L1 Cache,而LS2用于访问L2 Cache。这一说法源自AMD的软件优化手册[73],这似乎是一个权威说法,也在某种程度上善意地误导着读者。这一说法非但并不准确,在某种程度上甚至是错误的。Opteron LSU的结构示意如44所示。

4.2 <wbr>存储器读写指令的发射与执行2

Opteron微架构中,一条存储器读写指令在被DispatchInteger Scheduler的同时,也会被DispatchLS1的相应Entry中等待。LS1通过监听AGUTag总线获得必要的信息后,开始真正意义上的执行。这些必要的信息包括,LS1所需要的地址是否能够在下一拍有效,将使用哪一个AGU产生的地址。LS1使用Tag总线的信息虽然不能用于L1 CacheProbe操作,却可以实现AGULSU的流水执行。

Opteron微架构分离TagData总线是利用流水进行加速的技巧,将AGU的执行分解为两个步骤,以最大化AGULSU流水部件间的Overlap。除了AGU部件分离的TagData总线,LSUALU也进行了这样的总线分离。

LS1中的指令在下一拍从Data总线中获得地址后执行,由上文所述,Opteron微架构的L1 Cache具有两个端口,当所访问的数据间不发生冲突的前提下,LS1率先处理最先进入队列的两条存储器读写指令,并将其转交给L1 CacheController做进一步处理。

无论是存储器读还是存储器写操作,L1 CacheController都需要首先进行Probe操作。读操作发起的Cache Read Probe操作将带回数据。写操作发起的Cache Probe操作,也被称之为Probe-before-Write。进行这个Probe操作之前,需要准备好待写的Cache BlockProbe操作返回时将会带回数据,而当且仅当存储器写指令获得最终数据而且进行Commit操作之后,才能将数据真正写入。由于写入的数据在多数情况不能占满一个完整的Cache Block,此时需要和Probe操作带回的数据进行Merge后进行写入操作。

写操作的实现细节比上文描述的过程复杂得多。即便我们抛离了与Store Ordering相关的诸多和Memory Consistency的概念和各类Cache Write策略,没有考虑在Cache Write Hit时使用的Write-ThroughWrite-BackWrite-Once策略,没有考虑Cache Write Miss时使用的Write-Allocate,Write-ValidateWrite-Around策略。

我们首先考虑在进行Write Probe操作之前,在Cache流水线准备好一个未使用的Cache Block,到从存储器子系统获得数据后真正写入数据的这段延时。我们首先关注这个刚刚准备好的Cache Block在此时使用的状态信息,似乎MOESIF这几个状态都无法准确描述此时的这条Cache Block所处的状态。

MOESIF这些状态位仅是Cache Controller所使用的简单得不能再简单的状态位,仅是一个Stable状态,是Cache Block诸多状态中一个子集。一个Cache Block中还含有其他状态位,更为复杂的处理Race ConditionTransient状态位。在CacheCache间的总线中包含着诸多Coherence Message和各类Bus Transaction。如果进一步考虑多级Cache的组成结构后,Cache ControllerFSM使用的状态位和流程迁移的复杂程度令人叹为观止。

其次我们需要考虑存储器写操作在等待最终Commitment时所带来的延时。如上文所述,如果存储器读指令的访问结构在LSQ中命中时,微架构将不会读取L1或者更高层次的Cache,从而充分利用了这个延时。这个延时可以带来的另外一个好处,由于后续的存储器读指令可能需要读取相同的Cache Block,此时也要进行Probe Cache操作。在这个延时中,这两个Probe操作可以合并,从而在一定程度上降低了总线的Traffic。这些优化手段提高了存储器读写指令的效率,也带来了较大的系统复杂度。

Opteron LS1中的存储器读或者写操作,如果没有及时完成,例如存储器写指令没有及时地进行Commitment,将导致存储器写操作无法在LS1中完成,此外如果存储器读没有在L1 Cache中命中也无法及时完成时,这些在LS1中的指令都将进入LS2,从而为后续的存储器指令预留空间。这些预留可以为更多可能在L1 Cache Hit的存储器操作并发执行。从这个角度分析可以发现LS1主要用于Cache Hit的处理。

LS2中的所有存储器读写指令,包括LoadStoreLoad-Store指令将继续监听Cache Probe的结果,当发生Cache Miss时,需要将存储器读写请求转发给BUI(Bus InterfaceUnit)部件,BUI部件将根据需要从L2 Cache或者主存储器中获得最终数据。即LS2用于处理Cache Miss时,需要较长时间的存储器读写指令。

Opteron微架构中,采用了Non-Blocking Cache的实现方式,为每一条Miss存储器请求添加了一个MAB Tag(Missed Address BufferTag)之后再发送给BUI部件,同时为这些Miss请求在LS2中设置了Fill Tag。当Probe操作的数据从L2 CacheController返回时,其MAB Tag将与在LS2中的Fill Tag进行比较,进一步确认数据是否有效,并将LS2中的存储器指令的状态从Miss更新为Hit

Store指令将在LS2中停留更长的时间,直到该指令从流水线中按序退出后,才能将数据写入到存储器子系统中。当发生Misprediction或者Exception,微架构可以丢弃在LS2中的暂存的Store指令。只要Store指令没有离开LSU,都可以丢弃,当然这种丢弃是条件的,并不是随意丢弃。

Opteron微架构中,L1L2 CacheController将与LSU共同完成一次存储器读写操作。在L1L2 Controller中含有各类Buffer,和连接这些Buffer的通路。一次存储器访问指令,在通过指令流水后,将首先到达LSU,并由LSU将其请求转发至L1L2 CacheController,并由这些Cache Controller完成剩余的工作。

Cache Controller需要在保证Memory Consistency的前提下,将数据重新传递给LSU,完成一次存储器读写的全过程。在一个微架构中,Cache Controller是一个较为复杂的功能,由其管理的Cache流水线是整个微架构的精华。



[1]许多论文书籍认为F(reg,reg)指令不属于存储器指令。

0 0
原创粉丝点击