如何强制 L2 缓存未命中?

Kro*_*oka 5 cpu performance caching consumption

我想研究L2缓存未命中对CPU功耗的影响。为了衡量这一点,我必须创建一个逐渐增加工作集大小的基准,以便核心活动(每个周期执行的微操作)和 L2 活动(每个周期的 L2 请求)保持不变,但 L2 未命中与 L2 请求的比率增加。

谁能告诉我一个强制“N”次二级缓存未命中的 C 程序示例?

Bee*_*ope 3

通常,您可以通过随机访问大于该缓存级别的工作集来强制在某个缓存级别上发生缓存未命中1的工作集来强制在某个缓存级别上发生缓存未命中。

您预计任何给定负载未命中的概率类似于:p(hit) = min(100, C / W)p(miss) = 1 - p(hit)其中p(hit)p(miss)是命中和未命中的概率,C是相关缓存大小,W是工作集大小。因此,对于 50% 的未命中率,请使用两倍于缓存大小的工作集。

快速浏览一下上面的公式就会发现,它p(miss)永远不会是 100%,因为C/W当 W 趋向无穷大时,它只会趋于 0(而且您可能买不起无限量的 RAM)。所以你的选择是:

  1. 通过使用非常大的工作集(例如,4 GB 为 256 KB 提供 99% 以上的错过机会)来获得“足够接近”,并假装错过率为 100%。

  2. 应用公式来确定实际预期的未命中数。例如,如果您针对 256 KB 的 L2 缓存使用 2560 KB 的工作大小,则缺失率为 90%。因此,如果您想检查 1,000 次未命中的影响,则应进行 1000 / 0.9 = ~1111 次内存访问以获得大约 1,000 次未命中。

  3. 使用任何近似方法,然后使用 CPU 上的性能计数器单元实际计算发生的未命中次数。例如,在 Linux 上您可以使用PAPI,或者在 Linux 和 Windows 上您可以使用 Intel 的PCM(如果您使用 Intel 硬件)。

  4. 使用“几乎随机”的方法来强制达到您想要的未命中次数。上面的公式对于随机访问有效,但如果您选择随机访问模式,并注意不重复“最近”访问,则可以获得 100% 的错过率。这里的“最近”意味着对可能仍在高速缓存中的高速缓存行的访问。计算这到底意味着什么是很棘手的,并且详细取决于缓存的关联性和替换算法,但是如果您不重复上次cache_size * 10访问中发生的任何访问,那么您应该非常安全。

至于 C 代码,您至少应该向我们展示您尝试过的内容。基本轮廓是创建一个字节或整数向量或具有所需大小的任何向量,然后随机访问该向量。如果您使每次访问都依赖于先前的访问(例如,使用整数读取来计算下一次读取的索引),您还将获得该级别缓存的延迟的粗略测量。如果访问是独立的,则您可能会同时对缓存有多个未完成的未命中,并且每单位时间会出现更多的未命中。您对哪一门感兴趣取决于您正在学习的内容。

对于跨不同步长和工作集大小进行此类内存测试的开源项目,请查看TinyMemBench


1对于内核之间共享的缓存级别(例如,最近的英特尔芯片通常为 L3),这会有点棘手 - 但如果您的机器在测试时非常安静,它应该可以很好地工作。