L07 Memory II

Last Time in Lecture 6

动态随机存取存储器(DRAM)

  • DRAM是目前主存使用的主要形式。其通过小电容存储数据,需要定期刷新数据,因此被称为“动态”存储器。
    • 访问过程相对较慢,涉及多步骤操作:预充电、读取行、读取列

静态随机存取存储器(SRAM)

  • SRAM比DRAM更快,但成本更高。
    • 通常用于缓存,即存储常用数据的高速内存,并集成在处理器芯片上。

缓存的功能

  • 缓存在靠近处理器的地方存储一小部分常用数据(通常用SRAM)。
    • 缓存需要使用搜索机制来查找数据,并且当缓存满时,需要一个替换策略来为新数据腾出空间。

缓存利用的局部性

  • 缓存通过利用内存引用的两种可预测性来提升性能:
    1. 时间局部性:同一个地址很可能会在短期内被多次访问。
    2. 空间局部性:相邻的地址很可能会在短期内被访问。

Recap: Replacement Policy

组相联缓存中,当集合已满时,必须决定替换哪一行。常见的替换策略包括:

  1. 随机替换(Random)
    • 随机选择一行进行替换,简单但不总是最优。
  2. 最近最少使用(LRU)
    • LRU策略会替换最近最少使用的缓存行。该策略有效利用时间局部性,但在每次访问时都必须更新状态,开销较大。
    • 适用于较小的组相联缓存(如2路组相联)。对于4-8路组相联,通常使用伪LRU(如二叉树结构)来简化实现。
  3. 先进先出(FIFO)轮转(Round-Robin)
    • 按照缓存行被加载的顺序依次替换,通常在高关联度缓存中使用。
  4. 非最近最少使用(NMRU)
    • 一种FIFO变体,但不替换最近使用的行,适用于一些特殊场景。

替换策略的作用

  • 替换策略仅在发生缓存未命中(Miss)时生效。因为缓存命中时,不需要替换任何行。因此,替换策略的影响相对较小,被称为次级效应

Pseudo-LRU Binary Tree

工作原理

伪LRU二叉树是一种用于组相联缓存的替换策略,通常用于4路组相联缓存,因为完全实现LRU的开销较大,而伪LRU则提供了近似LRU的效果,同时显著减少了硬件复杂度。

  1. 2路组相联缓存
    • 只需要1位来表示LRU状态。如果命中某一路,则将LRU位设置为指向另一条路,表示其为“最近最少使用”的缓存行。
  2. 4路组相联缓存
    • 使用一个3位二叉树来记录每次访问的路径。
    • 当缓存命中时,沿着访问路径的每个节点的LRU位都被更新为指向另一边。
    • 当发生缓存未命中时,树的LRU位用于选择要替换的路径,即选择最不常被访问的路径。
    • 这种结构能够以较小的硬件开销模拟出较为合理的LRU替换策略。

举例说明

  • 在一个4路组相联缓存中,初始状态的伪LRU二叉树可能全部指向左边,意味着缓存优先替换右边的路径。当右边的路径被访问时,树的相应LRU位会更新为指向左边,确保下次替换时选择最不常使用的路径。

CPU-Cache Interaction (5-Stage Pipeline)

5级流水线与缓存交互

在现代处理器中,CPU和缓存之间的交互通常发生在5级流水线中的不同阶段。以下是各个流水线阶段如何与缓存进行交互的概述:

  1. 取指阶段(IF: Instruction Fetch)
    • 处理器从指令缓存(Primary Instruction Cache)中取回指令。
    • PC寄存器提供当前的指令地址,地址送入指令缓存,缓存返回命中的指令。
    • 如果发生缓存命中,指令继续进入下一个阶段。如果未命中,则需要从主存中加载指令,这会导致流水线暂停(插入气泡)。
  2. 译码与寄存器取值阶段(ID: Decode, Register Fetch)
    • 该阶段解析指令,并从寄存器文件中取出操作数。
  3. 执行阶段(EX: Execute)
    • 在此阶段,指令通过ALU进行计算,可能涉及地址计算、算术操作等。
  4. 访存阶段(MEM: Memory Access)
    • 该阶段访问数据缓存(Primary Data Cache)
    • 如果内存操作命中缓存,处理器从缓存读取数据并继续。如果未命中缓存,则需要从更低层级的内存层次结构(例如主存)中加载数据,并更新缓存,同时CPU可能暂停。
  5. 写回阶段(WB: Write Back)
    • 最后阶段将计算结果写回寄存器或内存中。

缓存未命中的处理

  • 当数据缓存未命中时,CPU可能会暂停流水线,直到数据从主存加载完成。缓存将会触发内存控制器从更低层的存储层次结构中加载数据。
  • 加载完成后,数据会写入缓存,并继续执行流水线中的操作。

总结

CPU与缓存的交互在流水线的多个阶段中至关重要,尤其在数据和指令访问时。伪LRU二叉树提供了一种有效的替换策略,减少了缓存未命中的可能性,从而保持流水线的高效运行。

Improving Cache Performance

平均内存访问时间(AMAT)

缓存性能的关键指标之一是平均内存访问时间(AMAT),其计算公式为: [ \text{AMAT} = \text{命中时间(Hit Time)} + \text{未命中率(Miss Rate)} \times \text{未命中惩罚(Miss Penalty)} ]

为了提升缓存性能,需要从以下三方面着手:

  1. 减少命中时间(Hit Time):加快缓存数据的读取速度,使处理器尽可能快地从缓存获取数据。
  2. 降低未命中率(Miss Rate):通过增加缓存大小或改进替换策略,减少缓存未命中的频率。
  3. 减少未命中惩罚(Miss Penalty):当发生未命中时,减少从主存加载数据的延迟时间。

缓存大小与命中时间的权衡

一个重要的设计决策是缓存的大小。在现代技术中,缓存大小约为8-32KB时,通常可以保证命中时间不超过1个时钟周期。增大缓存虽然能降低未命中率,但可能会增加命中时间,从而降低整体性能,特别是在深度流水线或乱序超标量处理器中,这些设计会让缓存设计变得更加复杂。


Causes of Cache Misses: The 3 C’s

缓存未命中的原因可以归结为3个C

  1. Compulsory Misses(必然未命中)
    • 当第一次访问某个缓存行时(也称为冷启动未命中),缓存中还没有该数据,因此会发生未命中。
    • 这种未命中不可避免,即使缓存足够大,因为这是数据第一次被访问。
  2. Capacity Misses(容量未命中)
    • 当缓存太小,无法容纳程序所需的所有数据时,发生容量未命中。
    • 即使使用最优的替换策略,数据依然会因为缓存空间不足而被替换掉,从而导致未来的访问发生未命中。
  3. Conflict Misses(冲突未命中)
    • 因为缓存的行映射策略,多个内存块可能会映射到相同的缓存行,即使缓存有足够的容量,这些数据块之间的映射冲突也可能导致未命中。
    • 这种未命中可以通过增加缓存的关联度(Associativity)来减少,理想情况下,完全相联缓存不会发生冲突未命中。

结论

通过理解和优化3个C中的未命中类型,设计者可以针对特定的应用场景选择合适的缓存大小和替换策略,进而提升系统的缓存性能。

Effect of Cache Parameters on Performance

缓存参数对性能的影响

  1. 更大的缓存大小(Larger Cache Size)
    • 优点:增大缓存大小可以有效减少容量未命中冲突未命中,因为更大的缓存可以容纳更多的数据,减少数据被替换的概率。
    • 缺点:增大缓存的同时会增加命中时间(hit time),因为更大的缓存意味着更复杂的结构,查找数据需要更多时间。
  2. 更高的关联度(Higher Associativity)
    • 优点:增加缓存的关联度(如从1路增加到2路或4路)可以显著减少冲突未命中,因为数据块有更多的选择存放位置,减少了映射冲突。
    • 缺点:提高关联度通常会增加命中时间,因为缓存需要在多个位置进行数据比较。
  3. 更大的缓存行大小(Larger Line Size)
    • 优点:增大缓存行大小有助于减少必然未命中(Compulsory Misses),因为每次加载更多的数据到缓存,可以减少首次加载时的未命中次数。
    • 缺点:更大的行大小也可能增加冲突未命中,因为每个缓存行占据更多的空间,导致映射冲突。同时,未命中时的惩罚(Miss Penalty)也会增大,因为加载的数据量增加,主存访问时间变长。

图表分析

图表展示了不同缓存大小和关联度下的未命中率以及未命中率的组成(基于3个C:容量、必然和冲突未命中)。

  1. 上图(总未命中率)
    • 1路关联缓存的总未命中率最高,随着缓存大小的增加,未命中率逐渐下降。
    • 提高关联度(例如从1路到8路)明显降低了未命中率,尤其是小缓存时的冲突未命中率显著减少。
  2. 下图(未命中率的组成)
    • 必然未命中在小缓存时占比很大,但随着缓存大小增大,必然未命中减少,因为更多数据可以保存在缓存中。
    • 冲突未命中随着关联度的提高而减少,尤其是1路关联的冲突未命中率较高,而4路及8路关联显著降低了冲突未命中。
    • 容量未命中的比例较为稳定,但在小缓存时占比较高,随着缓存增大,容量未命中减少。

结论

要优化缓存性能,需要综合考虑缓存大小、关联度和缓存行大小之间的权衡。更大的缓存和更高的关联度可以减少未命中,但会增加命中时间。设计者应根据具体的应用需求和硬件约束,选择最合适的缓存配置。

Recap: Line Size and Spatial Locality

缓存行大小与空间局部性

在缓存和内存之间,缓存行(line)是传输的基本单位。行的大小决定了从主存加载到缓存的数据块的大小,通常以字(word)为单位表示。图中展示了一个4字缓存行的例子,缓存行的大小为b = 2位。

  1. 地址分解
    • 标签(Tag):用来标识内存块是否在缓存中。
    • 行地址(Line Address):指定缓存行的地址,用于从主存加载该行。
    • 偏移(Offset):用于在一个缓存行内精确定位具体的字节或字。
  2. 硬件优势
    • 减少标签开销:较大的行大小意味着每个缓存行存储更多数据,因此需要的标签总数减少。
    • 支持快速突发传输:较大的行大小可以充分利用主存(DRAM)的突发传输能力,在一次主存访问中传输更多的数据。
    • 利用宽数据总线:宽总线支持较大的数据块传输,减少了主存访问的频率,提升了效率。

增加缓存行大小的缺点

  1. 冲突增多
    • 增加行大小意味着缓存中的行数量减少,导致可能的冲突未命中(conflict misses)增加,特别是当多个内存块映射到同一缓存位置时。
  2. 带宽浪费
    • 当程序仅访问缓存行中的部分数据时,加载整个较大的行可能会导致带宽浪费,因为未使用的数据也被加载到了缓存中。

图表分析

图表展示了未命中率缓存块大小(Block Size)之间的关系,基于不同大小的缓存。

  1. 趋势观察
    • 随着块大小(block size)的增加,未命中率(miss rate)在较小块大小时下降,但块大小超过某一阈值后,未命中率开始上升。
    • 对于较小的缓存(如4K、16K),块大小的增加会较快地引发未命中率上升,因为较大的块减少了缓存中的有效行数,增加了冲突。
    • 对于较大的缓存(如64K、256K),随着块大小的增加,未命中率下降的趋势较为平稳,表明较大的缓存能够更好地容纳较大的块。
  2. 结论
    • 缓存行大小的选择需要在减少必然未命中和增加冲突未命中之间找到平衡。
    • 较大的缓存能更好地适应较大的行大小,但如果行大小过大,仍会引发未命中率上升。

总结

缓存行大小的选择直接影响缓存性能。较大的行大小可以减少必然未命中,并提高传输效率,但可能会导致冲突未命中增加和带宽浪费。因此,设计者需要在行大小和缓存容量之间做出权衡,以优化整体性能。

Write Policy Choices

缓存命中时的写入策略

  1. Write-Through(直写)
    • 每次写操作时,数据同时写入缓存主存
    • 优点:实现简单,保证缓存和主存数据一致,易于设计和实现。
    • 缺点:写操作的流量较高,因为每次写操作都要更新主存,导致性能下降。
  2. Write-Back(回写)
    • 写操作时,数据仅写入缓存,只有当该缓存行被替换时才将数据写回主存
    • 优点:减少了写入主存的频率,提高了写操作的性能。
    • 缺点:需要维护一个脏位(dirty bit)来标识数据是否被修改,缓存行被替换时必须检查是否需要回写主存。需要处理每次加载/存储时主存可能发生0、1或2次访问。

缓存未命中时的写入策略

  1. No-Write-Allocate(非写分配)
    • 在写操作未命中时,数据只写入主存,不加载到缓存中。
    • 通常与Write-Through策略搭配使用,因为数据立即被写入主存。
  2. Write-Allocate(写分配)
    • 写操作未命中时,先将数据从主存加载到缓存中,再进行写操作。
    • 通常与Write-Back策略搭配使用,利用缓存来存储数据以减少对主存的频繁写入。

常见的策略组合

  1. Write-Through + No-Write-Allocate
    • 这种组合简化了缓存设计,写操作直接反映在主存中,不必在未命中时加载数据到缓存。
  2. Write-Back + Write-Allocate
    • 这种组合有效利用缓存,减少了对主存的写入频率,优化了写操作性能。

Write Performance

图中展示了缓存写入的执行过程:

  1. 地址解码:提供的写入地址被分解为标签(Tag)索引(Index)偏移(Offset)
    • 标签用于比较缓存行的标记,以确认缓存中是否存在需要写入的数据块。
    • 索引用于定位缓存中的具体行。
    • 偏移指定要写入的数据块中的具体字节或字。
  2. 命中(HIT):如果标签匹配,说明缓存命中,缓存的写使能信号(WE)被激活,数据写入对应的缓存行。

  3. 未命中(Miss):如果标签不匹配,说明缓存未命中,具体操作将根据写入策略(如Write-Through或Write-Back)决定是否直接写入主存或将数据加载到缓存。

总结

写入策略的选择对缓存性能有显著影响。Write-BackWrite-Allocate组合更适合需要频繁写入的应用,减少对主存的频繁访问。而Write-ThroughNo-Write-Allocate则在设计简单性和数据一致性方面有优势。

Reducing Write Hit Time

问题

写操作的命中时间较长,因为在内存阶段,写入需要两个时钟周期:

  1. 一个周期用于标签检查(Tag Check)
  2. 如果命中,则另一个周期用于数据写入

解决方案

  1. 设计支持读写的RAM
    • 使用可以在一个周期内同时执行读写操作的数据RAM。如果标签检查失败,则恢复旧值。
  2. 流水线写操作(Pipelined Writes)
    • 将待写入的数据保存在缓存前的单独缓冲区中,在进行下一次存储操作的标签检查时,完成缓存数据的写入。这种方式利用了流水线的重叠,减少了写操作的延迟。
  3. 全相联缓存(Fully-Associative Caches with CAM Tag)
    • 使用内容可寻址存储器(CAM)标签实现全相联缓存。仅在命中时启用字行(Word Line),从而加快写入操作。

Pipelining Cache Writes

流水线写操作的执行过程

图中展示了缓存写操作流水线的工作机制:

  1. 地址与数据的延迟写入
    • 处理器提供的标签(Tag)索引(Index)要写入的数据,都暂时存储在延迟写地址(Delayed Write Address)延迟写数据(Delayed Write Data)缓冲区中。
  2. 标签检查(Tag Check)
    • 当进行写操作时,缓存会同时进行标签匹配,检查是否发生缓存命中。
    • 如果命中,则从数据缓存部分中写入对应的数据。
  3. 数据写入重叠
    • 数据的写入并不是立即进行的,而是在下一次存储操作的标签检查时完成。这种方式利用了流水线的数据重叠,减少了等待时间。

总结

通过采用流水线写操作、设计支持并行读写的RAM以及使用全相联缓存,可以显著减少写操作命中时的延迟,从而提高缓存写操作的性能。这些策略通过重叠写操作与标签检查的过程,有效减少了写入过程中的停顿,使得缓存能够更快地响应写请求。

Write Buffer to Reduce Read Miss Penalty

问题描述

在处理器执行写操作时,可能会引发性能瓶颈,尤其是在读取和写入同时发生的情况下。特别是对于写回缓存(Write-Back Cache),缓存行被逐出时需要写回主存,而在直写缓存(Write-Through Cache)中,每次写操作都会直接写入主存,这会进一步增加内存的访问延迟。

解决方案:写缓冲区(Write Buffer)

写缓冲区用于优化写操作,减少由于写入主存而导致的延迟:

  1. 缓冲写回操作
    • 对于写回缓存,当缓存中的脏行被替换时,脏数据会被写入到写缓冲区,而不是立即写回主存。
    • 对于直写缓存,所有写操作都会首先进入写缓冲区,而不是直接写入主存。
  2. 优化读操作
    • 写操作时处理器不会因写入主存而暂停(stall),即处理器可以继续执行,而写缓冲区负责异步处理写入。
    • 当发生读未命中(Read Miss)时,可以允许读操作优先于写操作,提高系统响应速度。

写缓冲区的两种方案

  1. 简单方案
    • 当读未命中时,处理器会等待写缓冲区中的所有写操作完成,即等到写缓冲区清空再执行读操作。
  2. 更快的方案
    • 地址检查:当发生读未命中时,首先检查读请求的地址是否已经在写缓冲区中。
      • 如果读地址和写缓冲区的地址没有冲突,则允许读操作优先于写操作,避免等待写缓冲区清空。
      • 如果读地址和写缓冲区的地址匹配,则从写缓冲区中直接返回数据,而不是等待主存更新。

总结

通过引入写缓冲区,处理器可以避免在写操作期间发生停顿,从而提升性能。此外,使用地址检查的更快速方案可以确保读操作不必等待写操作完成,从而显著减少读未命中惩罚(Read Miss Penalty)

Reducing Tag Overhead with Sub-Blocks

问题

标签(Tag)大小过大会导致缓存的开销过高,特别是在缓存行较大时,标签的存储和管理会显著增加缓存的复杂性。

  • 简单解决方案:增大缓存行可以减少标签数目,但这种方式可能导致较大的未命中惩罚,因为未命中时需要加载更大的数据块。

解决方案:子块存放(Sub-Block Placement)

子块存放(也称为扇区缓存,Sector Cache)是一种将缓存行划分为多个较小的单元(子块)的技术。通过对每个子块独立地设置有效位,可以减少标签开销,并优化数据传输。

  • 子块有效位(Valid Bit): 每个子块都会有一个有效位,用于表示该子块是否包含有效数据。只有当子块未命中时,才需要从主存中加载该子块。

  • 部分加载: 当发生未命中时,系统只会加载未命中的子块,而不是整个缓存行,从而减少了不必要的数据传输。

  • 标签匹配检查: 在执行标签匹配时,除了标签外,还要检查子块的有效位。如果标签匹配且子块有效,则可以确认该数据块已经在缓存中。

举例说明

如图所示,地址100的缓存行中,所有子块都有效;地址300的行中,部分子块无效;地址204的行中,某些子块无效。这样的机制可以减少未命中时的数据传输量,同时优化标签存储。


Multilevel Caches

问题

单层缓存无法同时满足大容量高速访问的需求。通常,较大的缓存速度较慢,较快的缓存容量又较小。

解决方案:多级缓存

多级缓存通过在不同的层级上使用不同大小和速度的缓存来优化系统性能。

  • L1缓存(一级缓存)
    • L1缓存靠近CPU,速度非常快,但容量较小。它主要用于存储最常访问的指令和数据。
  • L2缓存(二级缓存)
    • L2缓存比L1缓存大得多,速度稍慢。它作为L1缓存的后备,存储那些不常用但仍可能被访问的数据。
  • 主存(DRAM)
    • 主存容量最大,但访问速度最慢,通常只有当L1和L2缓存都未命中时才会访问主存。

多级缓存中的未命中率

  1. 局部未命中率(Local Miss Rate)
    • 局部未命中率衡量的是某一级缓存的未命中次数占该缓存总访问次数的比例: [ \text{Local Miss Rate} = \frac{\text{Misses in Cache}}{\text{Accesses to Cache}} ]
  2. 全局未命中率(Global Miss Rate)
    • 全局未命中率指的是某一级缓存的未命中次数相对于处理器对内存的总访问次数: [ \text{Global Miss Rate} = \frac{\text{Misses in Cache}}{\text{CPU Memory Accesses}} ]
  3. 每条指令的未命中数(MPI)
    • MPI(Misses Per Instruction)表示每执行一条指令时发生的平均未命中次数: [ \text{MPI} = \frac{\text{Misses in Cache}}{\text{Number of Instructions}} ]

总结

通过引入子块存放机制,缓存可以在减少标签开销的同时,优化数据传输量。而多级缓存通过不同层次的缓存大小和速度平衡了容量与性能,使得系统能够有效地加快数据访问速度。

Miss Rates vs Cache Size for Multilevel Caches

图表分析

图表展示了多级缓存中不同缓存大小对未命中率(Miss Rate)的影响。它比较了局部未命中率(Local Miss Rate)、全局未命中率(Global Miss Rate)和单层缓存未命中率(Single Cache Miss Rate),并分析了缓存大小从4KB到4096KB对这些未命中率的变化。

  1. 局部未命中率(Local Miss Rate)
    • 图中的局部未命中率(黑色圆点线)显示,当缓存大小达到64KB时,局部未命中率降到4%左右。随着缓存大小的增加,局部未命中率逐渐下降,最终在1024KB及以上时接近1%。
  2. 全局未命中率(Global Miss Rate)
    • 全局未命中率(黑色方块线)下降得更快,在256KB时全局未命中率就低至3%,并在1024KB及以上时达到1%。
  3. 单层缓存未命中率(Single Cache Miss Rate)
    • 单层缓存的未命中率(灰色线)在缓存较小的情况下保持很高,尤其是在4KB时,未命中率高达99%。随着缓存大小的增加,未命中率逐渐下降,在256KB时已降到10%左右。

结论

  • 小缓存(如4KB至32KB)未命中率较高,随着缓存大小的增大,未命中率显著降低。
  • 在使用多级缓存系统时,即使较小的L1缓存未命中率较高,但通过L2缓存作为后备可以显著减少全局未命中率。
  • 缓存大小在256KB及以上时,进一步增大缓存的影响变小,因为未命中率趋于稳定。

Presence of L2 Influences L1 Design

多级缓存对L1设计的影响

  1. 较小的L1缓存
    • 如果系统中有L2缓存,L1缓存可以设计得较小。这是因为较小的L1缓存可以减少L1的命中时间,虽然L1的未命中率会稍微上升,但L2缓存作为备份可以有效减少L1未命中的惩罚。
    • 这种设计还能减少平均访问能耗,因为访问较小的L1缓存所需的能量较少。
  2. 更简单的直写L1缓存
    • 使用直写(Write-Through)L1缓存时,所有写入操作直接传递给L2缓存处理,而不是写回主存。这种方式能让L2缓存吸收写入流量,避免频繁写入主存,提高整体性能。
    • 直写L1的优势包括:
      • 流水线控制简化:每次L1缓存访问最多生成一个L2未命中请求,不会产生脏数据回写的额外请求。
      • 简化一致性问题:因为每次写入都通过L2缓存,减少了数据不一致的复杂性。
      • 简化错误恢复:可以在L1使用奇偶校验位来检测错误,若发现错误可以直接从L2缓存重新加载数据,而不必担心L1中的脏数据丢失。

设计影响

  • L1缓存更小和更简单:由于L2缓存的存在,可以在不显著增加系统未命中率的情况下,设计一个较小且高效的L1缓存。这减少了L1的设计复杂性和能耗,同时提升了整体缓存性能。

  • 直写策略与L2缓存结合使用:通过使用直写L1缓存写回L2缓存,可以减少写流量对主存的影响,同时简化了流水线和缓存一致性问题。

Inclusion Policy

Inclusive Multilevel Cache

  • 定义:内层缓存(L1)只能存储在外层缓存(L2、L3)中也存在的缓存行。
  • 特点
    • 缓存一致性(Cache Coherency):外部一致性侦听机制(如处理器总线上的snoop访问)只需检查外层缓存,因为所有被内层缓存存储的缓存行必然也存在于外层缓存中。
    • 优点:简化了缓存一致性协议,实现较为简单。

Exclusive Multilevel Cache

  • 定义:内层缓存(L1)和外层缓存(L2、L3)可以存储互不重叠的缓存行,内层缓存中的行可能不在外层缓存中。
  • 特点
    • 缓存交换(Cache Line Swapping):当发生未命中时,缓存行可以在内外层缓存之间交换,内层缓存的行被移到外层缓存,从而充分利用缓存的整体容量。
    • 实际应用:AMD Athlon处理器使用了64KB的一级缓存(L1)和256KB的二级缓存(L2),采用了独占缓存设计以提高缓存利用率。

比较

  • Inclusive 缓存适合于需要简化一致性管理的设计,但缓存的总容量利用率可能较低。
  • Exclusive 缓存能够更有效地利用内外层缓存的总容量,减少缓存行重复存储,但需要更复杂的管理机制。

Itanium-2 On-Chip Caches (Intel/HP, 2002)

Itanium-2处理器的片上缓存结构

  1. 一级缓存(L1 Cache)
    • 大小:16KB
    • 关联度:4路组相联(4-way set associative)
    • 缓存行大小:64字节
    • 端口:4个端口(2个读端口,2个写端口),可以同时进行多次加载和存储操作。
    • 延迟:单周期访问延迟
  2. 二级缓存(L2 Cache)
    • 大小:256KB
    • 关联度:4路组相联
    • 缓存行大小:128字节
    • 端口:4个端口(支持4次加载或4次存储操作)
    • 延迟:5个时钟周期延迟
  3. 三级缓存(L3 Cache)
    • 大小:3MB
    • 关联度:12路组相联
    • 缓存行大小:128字节
    • 端口:单个32字节宽的端口
    • 延迟:12个时钟周期延迟

总结

Itanium-2处理器采用了三级缓存架构,每一级缓存在容量、访问时间和并发能力上都有不同的设计:

  • L1缓存具有低延迟和多端口设计,适合高速访问;
  • L2缓存在容量和速度上进行了平衡,适合存储中等频率访问的数据;
  • L3缓存则提供了较大的容量,尽管延迟较高,但能够为处理器提供大量数据存储。

这种多级缓存的设计充分利用了片上空间和访问时间的权衡,确保了处理器的高效性能。

Power 7 On-Chip Caches [IBM 2009]

Power 7处理器的片上缓存结构设计充分利用了多级缓存架构来提升多核处理器的性能:

  1. 一级缓存(L1 Cache)
    • 32KB 指令缓存(I$)/核:每个核心都有专属的32KB一级指令缓存,用于高速访问经常执行的指令。
    • 32KB 数据缓存(D$)/核:每个核心还拥有32KB的一级数据缓存,用于存储经常访问的数据。
    • 延迟:L1缓存的访问延迟为3个时钟周期,确保高速的数据和指令获取。
  2. 二级缓存(L2 Cache)
    • 256KB 统一二级缓存/核:每个核心都有256KB的L2缓存,作为L1缓存的备份,用于存储更多的数据和指令,缓解一级缓存容量的不足。
    • 延迟:L2缓存的访问延迟为8个时钟周期
  3. 三级缓存(L3 Cache)
    • 32MB 统一共享三级缓存:所有核心共享一个32MB的L3缓存,使用嵌入式DRAM(eDRAM)技术。
    • 延迟:本地L3缓存的访问延迟为25个时钟周期,虽然较高,但它提供了大量的缓存容量,用于存储较不频繁访问的数据。
    • 作用:L3缓存通过跨核心共享,提高了多核处理器的数据访问效率,减少了访问主存的需求。

总结

Power 7处理器通过分层缓存结构(L1、L2、L3)提高了数据访问效率,平衡了缓存容量和访问速度。每个核心都拥有快速访问的小型L1和L2缓存,同时通过共享L3缓存减少内存带宽压力,适应了多核处理器的高并发需求。


IBM z196 Mainframe Caches (2010)

IBM z196主机采用了更复杂的缓存架构,以支持其高性能、并行计算需求。

  1. 一级缓存(L1 Cache)
    • 64KB 指令缓存(I$)/核:每个核心有64KB的L1指令缓存。
    • 128KB 数据缓存(D$)/核:每个核心还有128KB的L1数据缓存,确保高速指令和数据访问。
    • L1缓存的容量相对较大,以应对更频繁的缓存访问需求。
  2. 二级缓存(L2 Cache)
    • 1.5MB私有缓存/核:每个核心拥有1.5MB的私有L2缓存,总共144MB的L2缓存。较大的L2缓存有助于减少对主存的访问。
  3. 三级缓存(L3 Cache)
    • 24MB共享缓存/芯片:每个芯片配备24MB的L3缓存,使用嵌入式DRAM(eDRAM),总共576MB的L3缓存。
  4. 四级缓存(L4 Cache)
    • 768MB共享缓存/系统:L4缓存是全系统共享的768MB缓存,进一步扩展了缓存层级,以支持大型主机系统中海量数据的存储和高速访问。

总结

IBM z196主机通过多层缓存架构,包括L1、L2、L3和L4,确保每个核心可以快速访问大量的数据。这种设计对于大规模并行处理任务、主机系统的高吞吐量和低延迟访问需求具有重要作用。