4

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

任何人都可以向我展示一个强制“N”个 L2 缓存未命中的 C 程序示例吗?

4

1 回答 1

2

您通常可以通过随机访问大于该缓存级别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 为您提供 99%+ 的 256 KB 未命中率)来“足够接近”,并假装您的未命中率为 100%。

  2. 应用公式来确定实际预期的未命中数。例如,如果您使用 2560 KB 的工作大小来对抗 256 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)来说有点棘手 - 但如果您的机器在测试时非常安静,它应该可以正常工作。

于 2016-06-16T20:09:31.953 回答