在这个细节级别,您必须将“缓存”和“TLB”分解为它们的组成部分。它们在使用 VIPT 速度黑客与标签获取并行翻译的设计中非常紧密地互连(即利用所有索引位都低于页面偏移量,从而“免费”翻译。相关:为什么大多数处理器中L1缓存的大小都小于L2缓存的大小?)
L1dTLB 本身很小/速度很快内容可寻址存储器具有(例如)64 个条目和 4 路组关联(英特尔Skylake)。大页通常通过并行检查的第二个(和第三个)数组来处理,例如对于 2M 页面为 32 条目 4 路,对于 1G 页面:4 条目完全(4 路)关联。
但现在,简化你的心理模型并忘记大页面。
L1dTLB 是单个 CAM,检查它是单个查找操作。
“缓存”至少由以下几部分组成:
- 存储标签+数据的SRAM数组
- 控制逻辑根据索引位获取一组数据+标签。 (高性能 L1d 缓存通常与标签并行地获取集合中所有方式的数据,以减少命中延迟,而不是像使用更大、关联度更高的缓存那样等待选择正确的标签。)
- 比较器根据翻译后的地址检查标签,如果其中之一匹配,则选择正确的数据,否则会触发错误处理。 (并且在命中时,更新 LRU 位以将此方式标记为“最近使用”)。有关不带 TLB 的 2 路关联高速缓存的基础知识图,请参见https://courses.cs.washington.edu/courses/cse378/09wi/lectures/lec16.pdf#page=17. The
=
圆圈内是比较器:如果标签宽度输入相等,则生成布尔 true 输出。
L1dTLB 并未真正与 L1D 缓存分开。我实际上并不设计硬件,但我认为现代高性能设计中的加载执行单元的工作原理如下:
-
AGU 根据寄存器 + 位移生成地址。 (如果非零则为段基数。)
(有趣的事实:Sandybridge 系列乐观地缩短了此过程以实现简单的寻址模式:[reg + 0-2047]
如果 reg 值与以下地址位于相同的 4k 页中,则加载使用延迟比其他寻址模式低 1creg+disp
. 当基址+偏移量与基址位于不同页面时是否会受到惩罚?)
-
索引位来自地址的页内偏移部分,因此它们不需要从虚拟转换为物理。或者说翻译是无效的。这种具有 PIPT 缓存非混叠功能的 VIPT 速度只要满足以下条件即可发挥作用:L1_size / associativity <= page_size
。例如32kiB / 8 路 = 4k 页。
索引位选择一个集合。对于该组的所有方式,标签+数据都是并行获取的。 (这需要消耗电力来节省延迟,并且可能只对 L1 来说值得。更高的关联性(每组有更多的方式)L3 缓存绝对不值得)
-
在 L1dTLB CAM 数组中查找地址的高位。
-
标签比较器接收翻译后的物理地址标签和从该组中提取的标签。
-
如果存在标记匹配,则缓存会按照匹配方式从数据中提取正确的字节(使用地址的行内偏移量低位和操作数大小)。
或者,它可以更早地使用偏移位来从每路仅获取一个(对齐的)字,而不是获取完整的 64 字节行。没有高效未对齐负载的 CPU 肯定是这样设计的。我不知道这是否值得为支持未对齐负载的 CPU 上的简单对齐负载节省电量。
但现代 Intel CPU(P6 及更高版本)不会因未对齐的加载微指令而受到任何惩罚,即使对于 32 字节向量也是如此,只要它们不跨越缓存行边界即可。并行 8 路的字节粒度索引可能比仅获取整个 8 x 64 字节并在获取+TLB 发生时设置输出复用(基于行内偏移、操作数大小和)的成本更高。特殊属性,例如零或符号扩展或广播负载。因此,一旦标签比较完成,来自所选方式的 64 字节数据可能会进入已配置的多路复用器网络,该网络会获取正确的字节并进行广播或符号扩展。
AVX512 CPU 甚至可以执行 64 字节全行加载。
如果 L1dTLB CAM 中没有匹配项,则整个缓存获取操作将无法继续。我不确定 CPU 是如何设法将其管道化,以便在解决 TLB 未命中问题时其他负载可以继续执行;执行单元可能会在 L1dTLB 更新后重做加载或存储地址。该过程涉及检查 L2TLB(Skylake:4k 和 2M 的统一 1536 条目 12 路,1G 的 16 条目),如果失败,则进行页面遍历。
我假设 TLB 未命中会导致标签+数据获取被丢弃。一旦找到所需的翻译,它们将被重新获取。当其他负载运行时,没有地方可以存放它们。
最简单的是,它可以在翻译准备好时重新运行整个操作(包括从 L1dTLB 获取翻译),但它可以通过缩短流程并直接使用翻译而不是放入来降低 L2TLB 命中的延迟将其放入 L1dTLB 中并再次将其取出。
显然,这要求 dTLB 和 L1D 真正设计在一起并紧密集成。因为他们只需要互相交谈,所以这是有道理的。硬件页面遍历通过 L1D 缓存获取数据。 (页表始终具有已知的物理地址,以避免出现第 22 条规则/先有鸡还是先有蛋的问题)。
在 Intel CPU 上,显然加载 uop一旦调度器被调度就离开调度器到执行单元,因此它们不会从那里重播。也许加载执行单元或加载缓冲区条目跟踪待处理的 TLB 未命中?加载缓冲区条目跟踪正在进行的高速缓存未命中,但在这种情况下,地址转换已完成并且已知是无故障的,并且它们只需在数据到达时将数据转发到相关微指令。
从 TLB 到 Cache 是否有边带连接?
我不会将其称为边带连接。加载/存储 AGU 是only使用 L1dTLB 的事物。类似地,L1iTLB 仅由也读取 L1i 高速缓存的代码获取单元使用。 (页遍历硬件还需要更新 TLB 条目,可能与加载或存储地址执行单元分开。TLB 更新可以由硬件预取逻辑触发,以预取下一个虚拟页的 TLB 条目。)
如果有二级TLB,它通常是统一的,因此L1iTLB和L1dTLB都会检查它是否丢失。就像分离的 L1I 和 L1D 缓存通常会检查统一的 L2 缓存(如果它们未命中)。
外部缓存(L2、L3)非常普遍 PIPT。转换发生在 L1 检查期间,因此物理地址可以发送到其他缓存。