performance - 如何强制 L2 缓存未命中?

标签 performance caching cpu consumption

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

谁能给我看一个强制“N”个 L2 缓存未命中的 C 程序示例?

最佳答案

您通常可以通过随机访问大于某个缓存级别的工作集来强制在某个缓存级别发生缓存未命中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)。所以你的选择是:

  • 通过使用非常大的工作集(例如,4 GB 为您提供 99% 以上的 256 KB 未命中率)获得“足够接近”,并假装您的未命中率为 100%。
  • 应用公式来确定实际的预期未命中数。例如,如果您使用 2560 KB 的工作大小,而 L2 缓存为 256 KB,那么您的未命中率为 90%。因此,如果您想检查 1,000 次未命中的影响,您应该进行 1000/0.9 = ~1111 次内存访问以获得大约 1,000 次未命中。
  • 使用任何近似方法,然后使用 CPU 上的性能计数器单元实际计算发生的未命中数。例如,在 Linux 上您可以使用 PAPI,或者在 Linux 和 Windows 上您可以使用 Intel 的 PCM(如果您使用的是 Intel 硬件)。
  • 使用“几乎随机”的方法来强制您想要的未命中数。上面的公式对随机访问有效,但如果您选择访问模式使其随机,但需要注意的是它不会重复“最近”访问,您可以获得 100% 的未命中率。这里的“最近”是指对可能仍在缓存中的缓存行的访问。计算这究竟意味着什么很棘手,具体取决于缓存的关联性和替换算法,但如果您不重复上次 cache_size * 10 访问中发生的任何访问,您应该非常安全。

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

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

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

    关于performance - 如何强制 L2 缓存未命中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37862356/

    相关文章:

    Python: 需要使用 bash 一行

    linux - 当CPU中运行的进程离线时会发生什么

    performance - 执行redis操作的Go代码中缺少毫秒

    javascript - Angularjs 中使用 Bindonce 自定义指令值

    caching - 如何计算缓存开销?

    java - 在 Android 浏览器缓存中注入(inject)项目

    c++ - 沿 4 字节边界对齐

    javascript - javascript中for循环所花费的时间随着迭代次数的增加呈指数增长

    visual-studio - 如何在 Docker 镜像中应用最新的 msbuild?

    mysql - 使用 Redis 缓存 SQL 结果