VIPT缓存:TLB和缓存之间的连接?

Uch*_*chi 4 caching cpu-architecture tlb cpu-cache mmu

我只是想澄清这个概念,并且可以找到足够详细的答案,这些答案可以说明一切在硬件中的实际效果.请提供任何相关细节.

在VIPT高速缓存的情况下,存储器请求并行发送到TLB和高速缓存.

从TLB我们得到了经过翻译的物理地址.从缓存索引中我们得到标签列表(例如,来自属于一组的所有缓存行).

然后将翻译的TLB地址与标签列表匹配以找到候选者.

  • 我的问题是这次检查在哪里进行?
    • 在缓存中?
    • 如果不在Cache中,还有哪些地方?
  • 如果在Cache中执行检查,则
    • 是否有从TLB到Cache模块的边带连接,以获得与标签地址进行比较所需的翻译物理地址?

请问某人"实际上"如何实现这一点以及Cache模块和TLB(MMU)模块之间的连接?

我知道这依赖于具体的架构和实现.但是,当有VIPT缓存时,您知道的实现是什么?

谢谢.

Pet*_*des 6

在这个详细程度,您必须将"缓存"和"TLB"分解为其组成部分.它们在设计中非常紧密地互连,该设计使用与标签获取并行转换的VIPT速度黑客(即利用索引位全部低于页面偏移并因此被"免费"翻译.相关:为什么在大多数处理器中,L1缓存的大小是否小于L2缓存的大小?)

L1dTLB本身是一个小/快内容可寻址存储器,具有(例如)64个条目和4路组关联(Intel Skylake).Hugepages通常使用并行检查的第二个(和第三个)阵列来处理,例如,对于2M页面为32入口4向,对于1G页面:4入口完全(4向)关联.

但是现在,简化你的心理模型,忘记大片.L1dTLB是单个CAM,并且检查它是单个查找操作.

"缓存"至少包含以下部分:

  • SRAM数组,用于存储标记+数据
  • 控制逻辑,用于根据索引位获取一组数据+标签.(高性能L1d缓存通常与标记并行获取集合的所有方式的数据,以减少命中延迟,而不是等到选择正确的标记,就像使用更大的更高关联缓存一样.)
  • 比较器根据翻译的地址检查标签,如果其中一个匹配,则选择正确的数据,或触发错误处理.(并且在命中时,更新LRU位以将此方式标记为最近使用的)

L1dTLB与L1D缓存并不是真正独立的.我实际上并没有设计硬件,但我认为现代高性能设计中的加载执行单元的工作方式如下:

  • AGU从寄存器+偏移量生成地址.

    (有趣的事实:Sandybridge家族乐观地将此过程简化为简单寻址模式:[reg + 0-2047]如果reg值与4k页相同,则负载使用延迟比其他寻址模式低1c reg+disp. 当base + offset存在时会有一个惩罚吗与基地不同的页面?)

  • 索引位来自地址的页内偏移部分,因此它们不需要从虚拟转换为物理.或翻译是无操作.具有PIPT缓存的非别名的此VIPT速度与此一样长L1_size / associativity <= page_size.例如32kiB/8-way = 4k页.

    索引位选择一组.对于该集合的所有方式,并行获取标签+数据.(这需要节省延迟的功率,并且可能仅对L1有价值.更高的关联性(每组更多的方式)L3缓存绝对不是)

  • 在L1dTLB CAM阵列中查找地址的高位.
  • 标记比较器从该集合接收转换的物理地址标记和获取的标记.
  • 如果存在标记匹配,则高速缓存从数据中提取匹配方式的正确字节(使用地址的行内偏移量和操作数大小).

    或者不是取出完整的64字节行,而是可以先使用偏移位来从每个路中获取一个(对齐的)字.没有高效未对齐负载的CPU肯定是这样设计的.我不知道在支持未对齐负载的CPU上为简单对齐的负载节省电量是否值得.

    但是现代英特尔CPU(P6和更高版本)对于未对齐的负载微控制没有任何损失,即使对于32字节向量也是如此,只要它们不跨越缓存线边界即可.并行8种方式的字节粒度索引可能不仅仅需要获取整个8 x 64字节,并且在fetch + TLB发生时设置输出的复用,基于行内偏移,操作数大小,以及特殊属性,如零或符号扩展或广播加载.因此,一旦标记比较完成,来自所选方式的64字节数据可能只进入已经配置的多路复用网络,该网络抓取正确的字节并进行广播或符号扩展.

    AVX512 CPU甚至可以进行64字节的全线负载.


如果L1dTLB CAM中没有匹配,则整个缓存获取操作无法继续.我不确定CPU是否/如何管理这个,以便在解决TLB-miss时其他负载可以继续执行.该过程涉及检查L2TLB(Skylake:统一的1536条目12路用于4k和2M,16条用于1G),如果失败则用于页面漫步.

我假设TLB未命中导致标记+数据提取被丢弃.一旦找到所需的翻译,就会重新获取它们.在其他负载运行时,没有地方可以保留它们.

最简单的是,它可以在转换准备就绪时重新运行整个操作(包括从L1dTLB获取转换),但它可以通过缩短过程并直接使用转换而不是放置来降低L2TLB命中的延迟它进入L1dTLB并再次将其取回.

显然,这要求dTLB和L1D真正设计在一起并紧密集成.由于他们只需要相互交谈,这是有道理的.硬件页面遍历通过L1D缓存获取数据.(页面表总是有已知的物理地址,以避免捕获22 /鸡蛋问题).

是否有从TLB到Cache的边带连接?

我不会称之为边带连接.L1D缓存是唯一使用L1dTLB的东西.类似地,L1iTL仅由L1I高速缓存使用.

如果有一个二级TLB,它通常是统一的,所以L1iTLB和L1dTLB都会检查它是否错过.就像拆分L1I和L1D缓存一样,如果它们错过了,通常会检查统一的L2缓存.

外部缓存(L2,L3)是普遍的PIPT.在L1检查期间发生转换,因此可以将物理地址发送到其他缓存.