yee*_*haw 0 cpu intel cpu-architecture cpu-cache gem5
我想知道 L1-Dcache 是不是数据来自的终极缓存。因为我知道 i-cache,所以有一个更接近 CPU 的 DSB,可以看作是 L0-icache。
另外,我对哪些硬件更改会影响 DSB 的性能感兴趣?我的意思是缓存,有诸如缓存大小、缓存关联性之类的东西。但是,DSB 是否也只是会受这些因素影响的缓存?
如果是,我可以使用 gem5.dll 模拟结果吗?我知道使用 gem5,我可以配置 L1 指令缓存并观察 L1 指令缓存性能。如何在 gem 上为 DSB 做同样的事情?
我想知道 L1-Dcache 是不是数据来自的终极缓存
是的,或者存储缓冲区。 全局不可见加载指令解释了部分存储转发如何让内核加载一个从未全局可见的双字值,因此其他内核无法加载。
DSB(uop 缓存)是一个缓存,但它不缓存机器代码。它将解码 x86 机器代码的结果缓存为 uops。
它有各种限制,例如不能对来自同一个 32 字节 x86 机器代码块的 uops 使用超过 3 个“行”,因此建模并不像大小/关联性那么简单。例如,每条路(又名线)最多可容纳 6 个 uop,但以无条件(或预测采用)分支 uop 结束。来自多 uop 指令的所有 uop 必须在同一行中。
每个 x86 指令的融合域 uops 数量取决于它是什么指令;请参阅https://uops.info/,但请注意,取消层压意味着某些指令在问题/重命名阶段和 ROB 中比解码器和 uop-cache 需要更多的 uops。(微融合和寻址模式)
Agner Fog 的微架构指南有一些详细的测试结果(https://agner.org/optimize/),另见https://www.realworldtech.com/sandy-bridge/4/
Intel uop 缓存的基本参数,如 Sandybridge 部分 Agner 的微架构指南中所述:
µop 缓存被组织为 32 组 x 8 路 x 6 µops,总共最大容量为 1536 µops。它可以为每个对齐且连续的 32 字节代码块分配最多 3 行,每行 6 µops。
AFAIK,这种几何形状从 SnB 到 Skylake 和 Ice Lake 一直保持不变。
L1i 缓存包含uop缓存。uop 缓存是虚拟寻址的,因此不需要 TLB 查找。但我猜它也必须在 TLB 失效时被驱逐。(这不是一个大问题,因为传统解码器非常好;Sandybridge 系列避免了 P4 解码缓慢的问题,并尝试使用其跟踪缓存而不是普通的 L1i。)
请注意,AMD 的 Zen 微架构系列也使用 uop 缓存。他们不称它为 DSB,它可能与英特尔的有些不同。
另外,我对哪些硬件更改会影响 DSB 的性能感兴趣?
Skylake 将 uop-cache -> IDQ 的带宽从每周期 4 uop 增加到 6 uop。因此,即使在高吞吐量代码中,在气泡部分耗尽 IDQ 后,uop 缓存也可以“赶上”。
但是,它每个周期仍然只能读取 1 个 uop 缓存行,因此,例如在微代码更新禁用循环缓冲区 (LSD) 的 Skylake 上,一个通常每次迭代运行 1 个周期的小循环可以减慢到 2 个周期,如果循环被分成 32 字节的边界,因为这意味着它的 uop 将在 2 个单独的 uop-cache 行中。(比如每行 1 或 2 个。)
但是 Haswell可以在理想条件下从 uop 缓存中维持每个时钟 4 uop,即使使用每行 6 uop 完全打包 uop 缓存行的指令也是如此。因此,在 uop 缓存行获取和添加到 IDQ 之间显然存在一些缓冲,否则如果添加到 IDQ 的所有 uop 必须来自同一行,它将是 4:2 模式。