架构与原型
CPU流水线
a)MIPS五级流水线是什么样的?
1)MIPS五级流水线是阐述CPU流水线技术的经典简化模型。该流水线包括取指(instruction fetch,IF)、解码(instruction decode,ID)、执行(instruction execution,EX)、内存访问(memory access,MEM)、回写(write back,WB)。
2)IF阶段的公式为:IR⬅MEM[PC];PC⬅PC+4。其中,PC(program counter)表示程序计数器(或下一条指令的地址),IR(instruction register)表示存储待执行的指令。在此阶段,CPU根据PC值获取指令,同时PC会自动指向下一条指令。
3)ID阶段的公式为:A⬅REGS[IR[10:6]];B⬅REGS[IR[15:11]];Imm⬅IR[15:0]。其中A和B为操作数,Imm为立即数,REGS为寄存器文件。在这一级,CPU使用IR[10:6]和IR[15:11]作为寄存器索引从寄存器文件中读取操作数,或从IR[15:0]中提取立即数。
4)EX阶段的公式为:ALU输出⬅A+Imm(计算内存操作的有效内存地址);ALU输出⬅A op B(寄存器间操作);ALU输出⬅A op Imm(寄存器与立即数间操作);ALU输出⬅PC+Imm(计算分支指令的目标地址)。在此阶段,ALU可用于计算内存操作的有效地址、执行寄存器间或寄存器与立即数之间的运算操作、计算分支指令的目标地址。分支条件的判定也在此阶段完成。
5)MEM阶段的公式:LMD⬅MEM[ALU输出];MEM[ALU输出]⬅B(内存存储操作);if(条件满足) PC⬅ALU输出 else PC⬅PC+4。其中LMD是流水线寄存器,用于暂存从内存加载的数据。在此阶段将执行内存加载/存储操作。分支操作最终也在此周期内完成。若EX阶段判定的分支条件成立,则将PC更新为EX阶段ALU输出的目标地址,实现程序的跳转;否则程序将顺序执行,PC自动指向下一条指令。
6)WB阶段的公式:REGS[IR[20:16]]⬅ALU输出(寄存器间操作);REGS[IR[15:11]]⬅ALU输出(寄存器与立即数间操作);REGS[IR[15:11]]⬅LMD(内存加载)。在此阶段,最终结果写回寄存器文件。对于寄存器间操作,将ALU运算结果写入IR[20:16]指定的目标寄存器;对于寄存器与立即数间操作,将ALU运算结果写入IR[15:11]指定的目标寄存器;对于内存加载,将从内存读取的数据LMD写入IR[15:11]指定的目标寄存器。
b)流水线冒险及解决方案-基于MIPS五级流水线的案例
1)当多条指令并行执行时,CPU设计者必须解决三种冒险:结构冒险(structural hazards)、数据冒险(data hazards)、控制冒险(control hazards)。
2)结构冒险:结构冒险源于硬件资源竞争,当多条指令试图同时访问同一组硬件资源时就会导致冲突,这些资源包括寄存器文件和内存资源。同一时钟周期内,ID阶段指令需要读取寄存器文件,WB阶段指令需要写入寄存器文件。若寄存器文件只有一个端口,则会发生结构冒险。面对这样的问题,可以将时钟周期划分为前半周期(读操作)和后半周期(写操作)来解决,而更优秀的方案是为寄存器文件配置i独立的读写访问端口。同样的,同一时钟周期内,IF阶段需要从内存读取指令,而同时MEM阶段需要加载/存储数据,若指令和数据共享同一存储器,则会发生冲突。面对这样的问题,可以采用分离的指令存储器和数据存储器来解决。在现代的计算机体系结构中,这几乎是默认的设计方案,CPU通常配置独立的L1指令缓存和L1数据缓存。
3)数据冒险:数据冒险分为写后读(RAW)、读后写(WAR)、写后写(WAW)。只有RAW表示真正的数据依赖关系,其他两种只是名称依赖。在MIPS五级流水线中,WB阶段始终在ID阶段后,所以WAR和WAW不会发生。一种叫转发的技术可以解决RAW,ALU可以直接将其输出传递到输入,而非从寄存器文件中获取R3的值,从而第二条指令能够立即使用更新后的R3值。需要注意,R3并不能解决所有RAW冒险,例如:R3⬅MEM[addr];R5⬅R3+R4,此时R3的值需要等到MEM阶段结束后才可用,因此直接将ALU的输出传递到输入无助于第二条指令的正确执行。第二条指令需要暂停一个周期,以便R3的值能够从MEM阶段转发过来。
4)控制冒险:控制冒险发生在CPU试图在分支条件计算完成之前做出分支决策时。处理分支和控制冒险的方法:①可以暂停分支指令后的指令,直到分支条件确定,这意味着在分支指令到达MEM阶段之前,下一条指令无法执行,从而引入2个周期的停顿;②如果能在ID阶段(而非EX)阶段完成分支判定,则只需1个周期的停顿,这需要在ID阶段增加额外的ALU以提前计算条件,避免ID和EX阶段的结构冒险。但这种方法可能引起新的RAW冒险,例如R3⬅R1+R2;BEZ R3,分支指令需要在之前的指令后立即使用R3的值,由于R3的值要到EX阶段结束后才可用,因此分支前的2个时钟停顿仍然无法避免。
5)为了填补分支判定完成之前的停顿周期,可以用延迟槽技术。延迟槽中的指令总是会被执行,但这需要更复杂的编译器支持。编译器必须理解程序上下文,以确保填入延迟槽的指令不会破坏程序的逻辑。
6)分支预测可用于推测执行指令,但需要CPU具备预测错误时的恢复能力,如回滚机制。
7)最直接的方法就是停顿等待,但这会降低性能,违背流水线设计初衷,上述的停顿、分支判定、延迟槽、分支预测可分别用于应对不同类型的冒险。
c)能否任意增加CPU流水线的深度?
1)流水线的各阶段必须保持平衡,否则会出现瓶颈;
2)更深的流水线需要更多的硬件支持,例如,更多的流水线级间寄存器,以及更大的重排序缓存ROB以支持精确中断和硬件推测执行;
3)流水线需处理结构冒险、数据冒险、控制冒险,流水线越深,控制逻辑越复杂;控制冒险会使流水线刷新,导致实际性能难以达到理论峰值;数据冒险可能阻塞后续操作,限制指令级并行性发挥;
4)深流水线在物理设计上存在很多问题,如:clock tree balancing、clock skew、reset tree routing等;
5)加深流水线的初衷是通过增加级数来提高时钟频率和吞吐量,但工艺制程限制了频率上限。超过一定深度后,继续增加流水线级数无法带来性能提升,反而可能降低频率。
d)如何实现基于硬件的分支预测?
1)基于硬件的分支预测是优化控制冒险的关键CPU技术,主要涉及:分支条件预测、分支目标预测。分支条件预测决定是否执行分支,分支目标预测决定目标地址。
2)分支条件预测:分支条件预测由静态预测和动态预测组成。静态预测意味着分支要么总是执行,要么总是不执行。但现代CPU技术中,因为静态预测没有什么意义,比较过时,较少使用。动态预测最简单的是1位预测器,当状态为1时预测执行,反之预测不执行。如果预测不正确,则状态将翻转。为了进一步改进预测,可以使用2位预测器替换1位预测器。

目前我们讨论的预测器仅基于局部分支历史(即该分支自身先前的行为)。实际上,条件分支的行为还受程序执行路径的影响,这意味着最近的若干条件分支的全局历史也会影响预测准确度。常见的解决方法是采用(m n)关联预测器,其中m表示最近的m个分支的全局历史,n表示n位局部预测器。2位全局分支历史记录追踪最近2个分支的行为,用于索引具体选择哪一组2位预测器;每组2位预测器通过分支地址的最后4位进行索引(即每组包含16个2位预测器),最终预测结果由全局分支历史和分支地址共同决定。

终极解决方法是竞赛预测器,该方案让2个预测器同时工作并相互竞争,通过一个2位预测器来决定采用哪个预测器的结果。如果被选中的预测器连续两次预测错误而另一个预测正确,系统将转而采用另一个预测器进行分支预测。
3)分支目标预测:分支目标预测的目的是尽快获取分支跳转的目标地址,如果没有目标预测,即使提前知道分支应该执行,也无法确定跳转的目标地址。常见的实现方式是使用分支目标缓存(branch target buffer,BTB)来存储预测的分支目标地址。BTB的索引由分支指令的PC或程序计数器决定,预测的目标地址可以在一个周期内获取。
4)注意!分支预测只有在条件预测和目标预测同时存在时才能有效工作。
CPU乱序调度
a)Tomasulo算法如何工作?
1)在MIPS五级流水线中存在一个根本性的限制:一旦某条指令发生停顿stall,后续所有指令也将随之停顿,即使它们完全没有数据依赖关系。如果被停顿的指令需要很长时间才能完成,CPU流水线的吞吐量就会大幅下降。为了克服这一限制,现代CPU采用乱序调度out-of-order scheduling技术,其中tomasulo算法是典型算法。
2)算法概述:

所有指令按顺序从指令队列分发到对应的执行单元。流水线中包含多个执行单元(如存储单元、FP加法器、FP乘法器等),允许多条指令并行执行。每个执行单元附带若干个保留站用于缓冲待执行的指令,每个保留站包含以下字段:①Qp待执行的操作;②Qj/Qk产生操作数的保留站编号,若值为0,表示操作数已存在于Vj/Vk中或无需该操作数;③Vj/Vk源操作数的值,每个操作数仅V字段或Q字段之一有效;④A用于加载/存储指令的地址信息计算,初始存储指令的立即数字段,计算后存储有效地址;⑤BUSY标记该保留站及关联执行单元是否被占用。寄存器文件中每个寄存器附带一个Qi标签,表示正在计算该寄存器结果的保留站ID。若Qi为0,则说明当前没有活跃指令向该寄存器写入结果,寄存器值有效。系统通过公共数据总线CBD广播结果至所有需要使用该结果的位置。
3)tomasulo算法中的指令执行流程:在发送阶段,即使执行单元忙碌,只要存在空闲的保留站,指令仍可被发送。若源操作数已就绪,则直接复制到保留站的Vj和Vk字段,若操作数未就绪,将生成该结果的保留站ID记录到Qj和Qk字段。更新目标寄存器的Qi标签为当前保留站ID。在执行阶段,当所有操作数就绪且执行单元可用时,立即执行运算。在结果写回阶段,当运算完成且公共数据总线CDB空闲时,执行单元将结果广播到寄存器文件和其他保留站。

4)这种结果缓冲与寄存器文件写入的关联访问机制消除了写后写WAW冒险的问题。通过公共数据总线CDB,运算结果会广播传输到所有需要该结果的部件。这种数据前递机制有效解决了写后读RAW冒险。
b)Tomasulo算法中如何处理内存引起的数据依赖?
1)RAW、WAW、WAR冒险均针对寄存器操作。对于内存访问,同样存在三类隐性的数据依赖关系(但鲜少被提及),这些数据依赖关系包括RAW、WAW、WAR。需要注意:①内存数据依赖仅仅发生在访问相同地址时,若访问不同地址,加载/存储操作可以安全乱序执行;②在MIPS五级流水线中,所有内存访问均在MEM阶段串行化,故不会出现此类依赖,这里重点讨论的是CPU乱序调度场景。
2)RAW写后读依赖:Mem[Addr]⬅R1;R2⬅Mem[Addr]。若允许乱序执行,则读操作可能读到旧值,产生RAW依赖。
3)WAW写后写依赖:Mem[Addr]⬅R1;Mem[Addr]⬅R2。若允许乱序执行,则最终内存可能是R1而非R2,产生WAW依赖。
4)WAR读后写依赖:R1⬅Mem[Addr];Mem[Addr]⬅R2。若允许乱序执行,则读操作可能意外获取到新值,产生WAR依赖。
5)为了确定是否可以执行读操作,应该检查相同内存地址在读操作之前的所有未完成的加载/存储操作。同样,写操作必须等待,直到要操作的地址没有未完成的读操作或较早的写操作。
c)如何通过内存处理数据依赖?
1)在CPU乱序调度中处理数据内存依赖通常涉及两个关键步骤:①计算内存访问的有效地址;②检查所有乱序的加载/存储指令的地址,并确保存在冲突的加载/存储指令不会乱序执行。
2)加载/存储处理模型



d)如何在tomasulo算法中实现基于硬件的推测以最小化控制冒险?
1)上面讨论了tomasulo算法如何最小化数据冒险和依赖对性能的影响,但我们还可以优化控制冒险。关键思想在于基于分支预测来执行指令。现在的问题是,如果推测错误,如何恢复程序状态。
2)支持推测的tomasulo算法概述:tomasulo算法通过引入重排序缓冲区reorder buffer,将指令的完成与提交分离。指令结果可以基于预测提前生成,并在永久修改CPU状态(提交)之前将结果旁路传递给后续指令。重排序缓冲区提供了一种快速机制来撤销推测性状态更改:指令按顺序提交,如果重排序缓冲区的头部是一条错误推测指令,则会清空重排序缓冲区和CPU流水线。

3)重排序缓冲区(reorder buffer,ROB)将存储以下信息:①指令类型:分支/存储/加载/寄存器操作;②目标字段:结果应提交到的寄存器号或内存地址;③值字段:临时保存结果,直到指令提交;④就绪标志:标记结果是否已就绪并等待提交。
4)相较于不支持推测的tomasulo算法,支持推测的版本主要存在以下差异:①寄存器Qi标签:不再记录哪个保留站将产生结果,而是追踪哪个ROB条目会提交结果;②保留站Qj/Qk字段:改为跟踪哪个ROB条目将提交结果;③保留站Vj/Vk字段:可从寄存器文件或ROB条目复制。若值来自ROB条目,则这些值是推测性的。
5)tomasulo算法中的指令执行流程:
①发送阶段:只要有可用的保留站和ROB条目,指令即可被发送。指令类型、操作数、ROB条目编号存入保留站;指令类型和目标寄存器编号存入ROB条目;ROB条目编号会写入目标寄存器的Qi标签;②执行阶段:若所有操作数和执行单元就绪,则执行操作。对于加载/存储指令,此阶段完成有效地址计算;③结果写回阶段:当结果就绪且公共数据总线CDB空闲时,结果将广播到等待的保留站和对应的ROB条目。需要注意,此时结果尚未写入寄存器文件;④提交阶段:若ROB头部条目就绪且为非错误推测分支,则允许将结果更新到寄存器文件。对于存储指令,内存在此阶段更新。
6)推测执行下数据冒险与依赖的解决:①WAW/WAR内存依赖:由于存储指令按程序顺序更新内存,推测执行消除了这两项依赖;②RAW内存依赖:由于加载指令会按程序顺序对之前所有存储指令计算有效地址,且当存在相同内存地址的未提交存储指令时,加载不允许进入执行的第二阶段,因此RAW依赖也被消除。
虚拟内存和TLB
a)使用虚拟内存的好处?
1)CPU在虚拟地址空间中运行程序,目前讨论的所有内存地址本质上都是虚拟地址。虚拟地址需要转换为物理地址后,CPU才能访问系统内存。
2)虚拟内存使应用程序无需管理和分配共享内存空间。相反,程序可以在连续的虚拟内存空间中运行,而实际的物理内存空间可以是不连续的。物理内存的管理由操作系统负责。
3)借助虚拟内存,程序在概念上可以使用比物理内存更多的内存。例如,即使物理内存只有4GB,虚拟地址宽度也可以超过32位。存储空间可以通过整个硬盘进行扩展。
4)虚拟内存还通过内存隔离提高了安全性。在地址转换过程中,会检查可访问性。如果程序尝试写入只读的内存地址,写入操作会被阻止,并触发错误。如果程序尝试访问不属于它的内存地址,访问也会被阻止。
b)虚拟地址如何转换?
1)虚拟地址以页为粒度进行转换。操作系统会在内存中维护一个称为页表的数据结构,用于记录虚拟页到物理页的映射关系。页表通过虚拟页号进行索引。注意,页内偏移量在虚拟地址到物理地址的转换过程中保持不变。此外,页表还会存储页表的可访问性和安全信息,这些信息会在页表转换过程中进行检查。
2)

c)为什么需要TLB?
1)页表存储在主存中,每次内存访问都需要进行两次或更多次(如果涉及多级页表)内存访问。首先需要遍历页表,然后才能执行实际的内存访问,这种操作的开销很大。为了降低这一开销,可以为页表添加缓存,即转换后备缓冲器TLB。

2)在进行页转换时,会首先查找TLB。如果目标不在TLB内,才会访问页表。与普通缓存不同,页与页之间几乎没有空间局限性,因此TLB通常是全关联的。
d)如何处理TLB缺失?
1)通常有两种方法:①软件方法:TLB缺失会触发中断,操作系统介入检查页表并更新TLB。例如,MIPS和Alpha处理器采用这种方法;②硬件方法:由专门的硬件单元内存管理单元MMU负责在主存中遍历页表并更新TLB。例如,X86、SPARC、PowerPC。
e)如何处理缺页异常?
1)缺页异常发生在目标页既不在TLB中,也不在主存中时。如果发生缺页异常,必须首先通过磁盘IO读取将页表项加载到主存中。需要重点注意的是,无论TLB缺失如何被处理,缺页异常始终由操作系统负责处理。
精确中断的实现
a)什么是精确中断?什么是非精确中断?
1)精确中断应使得机器处于明确定义的状态。在精确中断处理过程中,指令的执行顺序应该得到严格维护。需要满足以下要求:
①程序计数器PC保存在已知位置;
②PC指向的指令之前的所有指令均已完全执行并改变了机器状态;
③PC指向的指令之后的所有指令均未执行或改变机器状态;
④PC指向的指令的执行状态是已知的。
2)非精确中断不满足上述所有要求。
3)理解精确中断的定义对于在流水线处理器中实现精确中断至关重要。
b)如何实现精确中断?
1)

2)方法1:结果移位寄存器→在该方法中,指令按顺序完成,并且需要维护一个结果移位寄存器。当发射一条需要i个周期完成的指令时,系统会保留j≤i的所有阶段。如果新发射的指令需要k个周期完成,但阶段k已被之前的指令占用,则该指令无法发射,必须等待。结果总线上设有逻辑电路,用于在指令完成时检查异常条件。如果检测到异常,控制逻辑会flush所有后续指令,确保它们不会影响机器状态。存储指令store只有在进入阶段1(即将完成)时,才能修改内存状态。同时,必须确保该指令之前的所有指令均无异常,以保证内存状态正确。由于结果移位寄存器存储了每条指令的PC,因此在发生异常时,PC会被作为保存状态的一部分,确保中断后可精确恢复。
3)方法2:待旁路的重排序缓冲区→该方案与支持推测的tomasulo算法类似。虽然指令可以乱序完成,但必须按程序顺序提交。当指令到达重排序缓冲区头部时,才会检查其异常状态。重排序缓冲区中的推测结果可旁路传输给后续新的指令。由于存储指令在抵达重排序缓冲区头部前不能修改内存,因此内存状态得以维护,保持稳定。PC值保存在重排序缓冲区中,确保异常发生时能够获取精确的PC状态。

4)方法3:历史缓冲区→该方案引入的组织结构类似重排序缓冲区的历史缓冲区。与指令提交时才更新寄存器文件不同,它允许指令完成
后立即修改寄存器文件,同时通过历史缓冲区维护寄存器文件的最后正确状态。检测到异常时,可从历史缓冲区恢复寄存器文件,并自尾部向头部清空活跃的历史缓冲区条目。为保持内存状态稳定精确,当存储条目退出历史缓冲区时,实际数据才会存储到内存中。因为历史缓冲区会保存PC值,所以PC状态也能保持精确。

5)方法4:未来文件→该方案与历史缓冲区类似,但采用两个独立的寄存器文件。架构寄存器文件反映架构机的状态,而未来文件在指令完成后立即更新。架构寄存器文件仅仅用于异常恢复,未来文件则超前于架构寄存器文件的运行,负责为功能单元提供操作数。存储指令仅当其位于重排序缓冲区头部时才更新内存,因此内存状态保持稳定精确。PC值存储在重排序缓冲区中,故PC状态也保持精确。

缓存
a)为什么需要缓存?
1)现代计算机存储体系包含多级结构:寄存器文件→缓存→主存/DRAM→SSD/HDD.没有缓存,性能下降,因为
①主存带宽有限:LPDDR5最高支持6400Mbps,LPDDR4最高支持4266Mbps,假设CPU运行频率为3GHz,寄存器宽度为32位,且每个周期都进行内存访问,则所需数据率为96000Mbps,远超LPDDR5带宽.
②主存访问延迟高:从发起内存操作到操作完成可能需要数百甚至数千个CPU周期.
③主存存在不可用时段:DRAM需要定期刷新以保持数据,刷新期间内存阵列不可访问.
2)缓存通常采用SRAM作为主存的数据缓冲区,它比DRAM更快匹配CPU频率,又比寄存器文件更大,可以提供更多的存储空间.
3)缓存的局部性原理
①时间局部性:CPU可能多次访问相同数据,例如,CPU执行循环时,循环内指令会被重复访问.若整个循环暂存于缓存,CPU只需首次从主存读取指令.
②空间局部性:CPU很可能访问相邻数据。缓存可以一次预取多条指令,减少多次访问。
4)缓存是寄存器文件的缓存,主存是SSD/HDD的缓存。寄存器和主存之间,由编译器或汇编程序员管理。缓存与主存之间,由硬件管理。内存与SSD/HDD之间,文件管理由程序员负责,虚拟内存则由硬件和操作系统共同管理。
b)什么是缓存冲突?
1)缓存的限制有4种,即4C。
①强制性缺失:发生在系统启动时。刚复位后,缓存是空的,任何缓存访问都会导致未命中;
②容量限制:缓存大小有限,理想情况下,如果缓存无限大,所有数据都能存入缓存,就不会有缓存缺失。但在实际系统,当缓存已满时,访问新的缓存块会导致缓存缺失;
③冲突缺失:不同的缓存块可能共享相同的缓存位置。一个后到的缓存块可能会替换掉先到的缓存块。
④一致性缺失:发生在缓存一致性系统中。例如,CPU A和CPU B处于缓存一致性系统中,缓存块X存储在CPU A的缓存中。如果CPU B需要写入X,缓存块X会被从CPU A的缓存块中移除。之后,如果CPU A再次访问X,就会导致缓存缺失。
2)通过增加缓存大小可以减少容量限制和冲突缺失,但强制性缺失和一致性缺失仍然存在。通过增加缓存关联度,可以减少冲突缺失,但其他缺失不变。
c)缓存中的读/写/替换策略是什么?
1)对于缓存设计有多种不同的选择,其中最重要的是缓存读策略、写策略、替换策略。
2)缓存读策略:缓存可以是直接映射direct-mapped、全相联fully-associative、组相联set-associative。
①直接映射:一个缓存块只能放在一个特定位置,由缓存块号决定。此时,缓存只存储标签和整个缓存块的数据。
②全相联映射:一个缓存块可以放在缓存的任何位置。此时缓存存储标签和缓存块数据。
③组相联缓存:介于直接映射和全相联之间。缓存被划分为多个组,一个缓存块只能存放在一个特定的组中,但组内的多个路是全相联的,因此缓存块可以存储在组内的任何位置。此时,缓存存储标签和缓存块数据。
→选择读策略时,需要考虑块冲突率、缓存利用率、控制逻辑复杂度、缓存访问速度等因素。
3)缓存写策略
①写直达write-through:同时更新缓存和主存
②写回write-back:仅在缓存块被替换时更新主存
写回缓存对内存带宽和缓存-内存总线带宽要求较低,写命中时更快,因为无需等待主存更新。写直达简化了IO,因为主存始终是最新的,但缓存命中时的延迟与缺失是相同的,其中的调度和替换更复杂。
③缓存缺失时也有两种写策略:非写分配和写分配。非写分配仅在缺失时更新主存,写分配则更新主存并将缓存块加载到缓存中。通常组合是:写直达+非写分配;写回+写分配。
4)缓存替换策略
①替换缓存的目标是识别和预测未来不再需要的缓存块。需要注意,直接映射缓存不适用于替换策略,因为每个缓存块都有固定位置。替换策略包括随机替换、最近最少使用、最不经常使用、先进先出等。
d)如何衡量缓存性能?
1)从CPU角度来看吗,衡量缓存性能最重要的指标是平均内存访问时间。
2)平均内存访问时间定义1=缓存命中率×命中延迟+(1-缓存命中率)×未命中惩罚
3)缓存读取策略决定了缓存命中延迟。在缓存命中时,首先需要检查数据是否在缓存中,找到数据在缓存中的存储位置,然后从缓存中获取数据。
4)平均内存访问时间定义2=指令比例×指令缓存平均访问时间+数据比例×数据缓存平均访问时间
5)若缓存增大是通过增加缓存行大小实现的,则加载缓存行的时间会变长,进而增加了未命中惩罚和平均内存访问时间。若缓存增大是通过提高关联度实现的,则命中延迟和平均内存访问时间可能增加,因为高关联度缓存的物理实现较复杂。
e)用虚拟地址访问缓存会有什么问题?
1)CPU在虚拟地址中运行程序,那么它是用虚拟地址还是物理地址访问缓存?答案是都可能。使用虚拟地址访问缓存需要考虑下面的问题:
①同形异义词:不同物理块可能拥有相同的虚拟地址,这是由上下文切换或显式重映射导致的,解决方案包括:每次上下文切换时清空/刷新缓存;在虚拟地址中附加进程ID;重映射时清空/刷新相关缓存块;
②别名:同一物理块可能对应多个虚拟地址,导致该块被重复缓存,引起一致性问题(通常由多进程共享引起)。解决方案包括:每次上下文切换时清空/刷新缓存;硬件确保缓存中仅保留一份副本;
③IO问题:DMA可能读写当前已缓存的物理地址块,解决方案包括:操作系统确保相关块不被缓存;使用物理地址目录进行侦听;使用包含式物理L2缓存。
f)根据索引位和标签tag位,缓存有哪些类型?
1)PIPT缓存(物理索引-物理标签缓存):在PIPT缓存中,索引位和标签位均使用物理地址。PIPT缓存结构简单,且避免了同形异义词和别名问题。然而,PIPT缓存在性能上存在缺陷,必须先完成地址转换,才能进行缓存查找,因此其实用性受到限制。
2)PIVT缓存:索引位使用物理地址,标签位使用虚拟地址。与PIPT缓存类似,必须先完成地址转换才能进行缓存查找,因此实用性较低。
3)VIPT缓存
4)VIVT缓存
缓存一致性
a)什么是NUMA/UMA架构?
1)CPU流水线和乱序调度是提升指令级并行性ILP的重要技术,而更高层级的并行性是线程级并行性TLP。实现TLP的一种方案是多处理器系统,即由多个处理器组成的计算机系统。这些处理器通常由单一操作系统控制,并共享相同的内存地址空间。
2)一般来说,有两种主要的多处理器架构:统一内存访问UMA、非统一内存访问NUMA。
3)UMA架构
①UMA架构是一种对称的集中式共享内存架构,所有处理器对内存的访问延迟是相同的。这种架构通常用于不超过八个处理器的系统中。UMA架构虽然简单,但其共享的最后一级缓存和连接所有处理器的总线将会成为系统瓶颈。

②NUMA架构:分布式共享内存设计,内存访问延迟取决于数据在内存中的位置。内存的分布式使得系统更易于扩展,但其主要缺点是处理器之间的数据通信也变得更加复杂。

b)什么是缓存一致性?
1)在NUMA/UMA架构中,不同处理器缓存共享数据会带来新的问题,这是因为每个处理器通过各自的缓存维护对内存的试图。缓存一致性的重要作用是避免不同处理器读取同一数据的不同值。
2)缓存一致性意味着对数据的任何读取都应该返回该数据最近被写入的值。
c)实现缓存一致性的两种基本方法?
1)基于目录的方案:目录会记录内存块的共享状态。在UMA中,这种方法很容易实现,因为目录可以与集中式内存或系统总线关联。在NUMA中,基于目录的方案不适用,因为目录会引入系统性能瓶颈,而这正是NUMA试图避免的。
2)基于侦听的方案:与基于目录的方案不同,内存块的共享状态分布在不同缓存中。在UMA中,缓存块通常通过系统总线访问,每个缓存控制器会侦听总线,决定是否为其他处理器的请求提供数据,并切换缓存状态。在NNUA中,侦听通常与目录结合使用。缓存控制器需要向对应的主存发送请求,而与该主存关联的目录决定是直接提供数据,还是从其他缓存中获取数据。而基于侦听的方案中,有两种基本方法:
①写无效:在写入时使得其他副本无效,通常只有一个缓存可以保留写入的副本,其他缓存中的副本必须被标记为无效,这是最常用的方法;
②写更新:每当对缓存块进行写入时,更新后的值会广播到所有缓存。这种方法不常用,因为广播需要占用大量带宽。
d)侦听的MSI协议状态转换



→MESI/MEOSI/MEOFSI协议
→如何为MESI协议实现主目录。。。
通用片上总线协议
a)APB协议的工作原理
1)APB是一种常用的非流水线协议,通常用于低成本、低功耗、低带宽的接口。APB每次传输至少需要2个时钟周期来完成。

①IDLE:APB的默认状态;
②SETUP:当需要传输时,PSELx信号被置位,总线进入SETUP设置阶段。总线仅在SETUP状态停留一个时钟周期,并在下一个时钟上升沿进入ACCESS状态。因此,从机必须在SETUP状态采样地址和控制信息;
③ACCESS:PENABLE信号置位以进入ACCESS状态。在ACCESS状态下,PADDR、PWRITE、PSELx、PWDATA信号必须保持稳定。
2)



b)AHB协议的工作原理
1)与APB不同,AHB是一种流水线化的高性能协议,它支持多主机/从机、突发传输、流水线操作。每次AHB传输至少需要2个时钟周期来完成,第一个周期称为地址传输阶段,第二个周期称为数据传输阶段。

等待状态可以通过延长数据阶段插入到AHB传输中。

2)一次AHB传输的地址阶段可以与另一次AHB传输的数据阶段重叠,从而实现流水线操作。然而,如果一次传输的数据阶段被延长,则紧随其后的传输的地址阶段也会被延长。然而,如果一次传输的数据阶段被延长,则紧随其后的传输的地址阶段也会被延长。

3)AHB提供了强大的突发操作功能。它使用突发大小信号HBURST来指示突发中的数据节拍数量,支持4/8/16节拍的突发、不定长度突发以及单次传输。它还支持增量突发(突发访问连续地址,每次传输的地址都是前一次地址的增量)和回环突发(当传输跨越地址边界时地址回绕)。
c)AXI协议的工作原理
1)与AHB协议类似,AXI是一种高性能、高频率的协议,支持多主机/从机和突发传输。AXI采用多主机/多从机和突发传输。AXI采用多组专用通道分别处理读写传输,并新增了多项特性,包括支持多笔未完成请求、支持乱序事务响应、通过字节选通实现非对齐数据传输等。


2)每个通道都包含了VALID有效和READY就绪信号对,用于传输握手机制。只有当VALID和READY同时有效才能进行数据传输。需要注意,READY可以依赖VALID信号,但VALID绝对不能等待READY信号,这是为了避免死锁。
3)每个通道都带有ID标签,用于区分多笔未完成事务,并将乱序响应与对应请求关联。对于同一个主机,相同ID的事务必须按序完成,但不同ID的事务可以任意顺序完成。这使得较快的传输可以优先于较慢的传输完成,即使较慢的传输先发起。例如,DRAM访问的请求-响应延迟具有不确定性,较早发出的请求可能响应较晚,而较晚发出的请求可能先获得响应。允许未完成事务和乱序响应能显著提升系统吞吐量和性能。
4)AXI协议以突发传输形式交换数据。每个突发包含多beat数据传输。事务起始阶段发送的控制信息会指明传输的突发长度AxLEN、每拍大小AxSIZE、突发类型AxBURST。
5)AxLEN表示突发传输的拍数。4位宽度支持最多16拍传输。无论组件是否使用所有数据,都必须完成AxLEN指定的所有拍数。AxSIZE定义每拍字节数,111表示最大128字节/拍,实际每拍大小不能超过总线宽度。AxBURST定义突发类型。AXI协议支持三种类型的突发:固定突发、增量突发、回环突发。固定突发表示每拍地址不变,典型应用如FIFO。
d)为什么AXI和AHB协议提供回环突发传输?
1)考虑缓存字优先场景。缓存以缓存块为单位组织数据,每个缓存块包含多个字(数据节拍)。如果总线主机只需要缓存块中的最后一个字(数据节拍),那么回环突发可以帮助先获取这个关键字,而总线主机可以继续执行后续操作。如果总线主机只能发起增量突发,那它必须等待整个缓存块填充完成后,才能获取所需数据。
2)假设有一个64字节的缓存块,每个字(数据节拍)的大小为4个字节,且关键字是缓存块中的最后一个字。与增量突发相比,回环突发可以为总线主机节省15个周期。
e)AXI协议中通道之间有哪些依赖关系?
1)W通道内部:W通道必须保持与AW通道相同的顺序,B通道必须在AW通道的传输成功和W通道的最后一个数据传输完成后返回。即写响应依赖于写请求和写数据。对于同一个总线主机,相同ID的写事务必须按顺序完成,但不同ID的写事务可以按任意顺序完成。
2)R通道内部:R通道必须在AR通道传输成功后返回。即读数据响应依赖于读请求。对于同一总线主机,相同ID的读事务必须按顺序完成,但不同ID的读事务可以按任意顺序完成。
3)W通道和R通道之间没有顺序要求。
f)如何强制AXI写通道和读通道之间的顺序?
1)至少有两种方式:通过屏障强制或源端强制。
2)通过屏障强制
①屏障事务提供系统中事务顺序和可见性的保证。如果屏障前的写请求更新了某些数据,那么屏障后的读请求将保证观察到更新后的数据,从而强制实现RAW依赖。类似的,如果屏障前的读请求读取了某些数据,屏障后的写请求更新了同一数据,则强制实现WAR依赖。
②总线主机需要以屏障对的形式发起屏障事务,即在AR和AW通道上各发起一个屏障事务。随后,读屏障响应通过R通道返回,写屏障响应通过B通道返回。在AR或AW通道中,任何在屏障事务之前发起的事务被定义为屏障前的事务。只有在读屏障响应和写屏障响应都收到后发起的事务才被视为屏障后的事务。
③注意,可能存在既不是屏障前也不是屏障后的事务,这些事务与屏障无关。
3)在源端强制
①AXI写通道和读通道的顺序可以在源端强制。例如,如果要在内存中实现一个FIFO结构,可以为读主机分配一个读信用计数器,为写主机分配一个写信用计数器。初始时,读信用计数器为0(表示内存中没有数据),写信用计数器初始化为FIFO大小(表示写主机有全部空间可写入)。
②只要写信用计数器不为零,写主机就可以继续向FIFO写入数据。写主机在发起写请求后递减信用计数器,如果写信用计数器递减到零则必须停止。当写响应返回后,写主机将信用传递给读信用计数器。读数据随后可以发起读请求,并在每次发起读请求时递减信用计数器。读主机只有在信用计数器非零时才能发起读请求。当主机收到读数据响应后,将信用返还给写信用计数器,通知写主机有可用空间写入更多数据。
g)AXI协议的独占访问是什么?
1)独占访问是AXI协议提供的一种信号量类型操作和原子访问机制。AXI协议通过AxLOCK信号指示独占访问。
②独占访问的步骤:总线主设备发起对一个地址的独占读请求→一段时间后,总线主机尝试通过发起对同一地址的独占写请求来完成独占操作,且AWID必须与独占读时使用的ARID匹配→如果总线主机收到EXOKAY响应,则独占写成功,并更新内存。这意味着自独占访问以来,没有其他主机写入该地址→如果总线主机收到OKAY响应,则独占写失败,内存位置不会被更新。这意味着自独占写访问以来,其他主机已经写入该地址。