如何清除L1,L2和L3缓存?

时间:2014-05-15 22:26:07

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

我正在进行一些缓存性能测量,我需要确保缓存是空的"有用"时间前的数据。

假设L3缓存为10MB,则可以创建10M / 4 = 2,500,000个浮点数的向量,遍历整个向量,对数字求和,并清空其中的任何数据的整个缓存迭代向量?

3 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:2)

这取决于你是多么疯狂地获得保证。

x86_64 L3高速缓存是物理索引的,虽然在虚拟空间中线性的10MiB块几乎肯定会在装载得很轻的机器上实际连续,但它无法保证。

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

此外,由于每个切片(至少在新的Sandy / Ivy Bridge上)连接到不同的核心,并且给定物理地址所在的切片由一些低/中间地址位的散列决定,可能必须使一个阵列略大于L3的大小,以对抗微小不均匀的重叠。

此时,线性地擦洗阵列几次应该可以解决问题。

答案 2 :(得分:0)

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

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

一个问题是它需要ring-0权限。另一个原因是它并不能保证在任何序列化点之前完成冲洗,因此它不足以保证系统的非波动性,但只要你可以阻止随后的WB进食就足够基准提高你的内存带宽。

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