【问题标题】:How to clear L1, L2 and L3 caches?如何清除 L1、L2 和 L3 缓存?
【发布时间】:2014-07-04 13:53:10
【问题描述】:

我正在做一些缓存性能测量,我需要在计时之前确保缓存中没有“有用”数据。

假设 L3 缓存为 10MB,是否足以创建一个 10M/4 = 2,500,000 个浮点数的向量,遍历整个该向量,对数字求和,然后清空整个缓存中的任何数据遍历向量?

【问题讨论】:

  • 如果你想清除缓存,只要拉一堆与你的测试数据无关的数据就可以了。
  • @Mysticial 嘿 Mystical,我的 vector 想法得到你的认可了吗? 2,500,000 够不够?由于缓存集关联性,我不确定。
  • 是的,只是memset() 任何大的连续内存块。一些处理器具有散列的 L3 缓存。因此,由于冲突,一块与缓存大小完全相同的连续内存可能会不够用。但我会说拉几百 MB 就足够了。
  • 问题和答案都是关于L3缓存的,但是题目问的是L1/L2/L3。您应该知道,L1 和有时 L2 缓存是每个内核,通过清除 L3 缓存,如果您的程序切换内核,您仍然可能会遇到问题。

标签: c++ performance caching cpu cpu-architecture


【解决方案1】:

是的,这足以刷新L3 的有用数据缓存。

我已经进行了类似类型的测量,并使用英特尔的缓存计数器进行了交叉验证,以验证我在测试期间是否发生了预期数量的L3 缓存未命中。

如果您想绝对确定,您还应该使用计数器。特别是,您可以在大多数英特尔架构中使用Event select 2EH, Umask 41H 测量最后一级缓存未命中。

有关这些计数器的详细信息,请参阅Intel Manual

【讨论】:

  • 嗨@merlin2011,你能把你在某个网站上进行的测试发给我看的链接吗?我试图执行相同的测试以证明 L3 缓存确实被清理了,但我无法做到。
【解决方案2】:

这取决于你为了得到保证而努力的疯狂程度。

x86_64 L3 缓存是物理索引的,虽然在虚拟空间中线性的 10MiB 块几乎肯定会在轻量内存负载的机器上物理上连续,但不能保证。

例如,Sandy 和 Ivy Bridge 在 2MiB 切片中具有 L3 缓存,具有 16 路集关联性(128kiB 步长),因此您可以通过调用 MAP_HUGETLB mmap() 来保证物理覆盖,假设标准为 2-4MiB大页面。

此外,由于每个切片(至少在新的 Sandy/Ivy Bridge 上)都连接到不同的内核,并且给定物理地址所在的切片由一些低/中位地址位的哈希确定,所以您可能必须使数组的大小略大于 L3 的大小,以应对微小的不均匀重叠。

此时,线性擦洗你的数组几次应该可以解决问题。

【讨论】:

    【解决方案3】:

    另一种选择是使用某些 ISA 提供的专用缓存失效指令。例如 x86有wbinvd 用于此目的(或clflush 用于单行)。

    http://x86.renejeschke.de/html/file_module_x86_id_325.html

    一个问题是它需要 ring-0 权限。另一个是它不保证在任何序列化点之前完成刷新,因此不足以保证系统的非易失性,但它可能足以进行基准测试,只要您可以防止随后的 WB 吃掉增加你的内存带宽。

    如果您能克服这些问题,在某些情况下,这可能是一个更好的解决方案,而不是仅仅为了确保缓存被刷新而检查一些大型数据结构。一些 CPU 可能会决定避免缓存他们认为将来不会重用的提取(有几篇关于这些选项的论文,至少有些声称它是在真实 CPU 中实现的)

    【讨论】:

      猜你喜欢
      • 2020-05-19
      • 2011-03-27
      • 2017-03-10
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2021-11-24
      相关资源
      最近更新 更多