【问题标题】:Can "non-native" pointers hurt cache performance?“非本机”指针会损害缓存性能吗?
【发布时间】:2013-11-26 02:23:28
【问题描述】:

据我所知,硬件预取器至少会检测并获取内存中的恒定步幅。此外,它可以monitor data access patterns,无论这意味着什么。这让我想知道,硬件预取器会根据存储在内存中的实际数据做出决定,还是纯粹基于程序表现出的行为?

我问的原因是因为我偶尔会使用“非本地”指针作为指针。一个简单的例子是一个预先分配的数组,以及索引这个数组的小整数而不是指针。如果我需要存储大量这样的“指针”,那么节省的内存可以快速增加,进而通过使用更少的内存间接提高缓存性能。

但据我所知,这可能会干扰硬件预取器的工作方式。或不!

我当然可以想象,不管现实与否,一个预取单元检查进入 L1 高速缓存的本地指针地址的高速缓存行,并开始将它们提取到 L2 或类似的东西中。在这种情况下,我节省内存的巧妙技巧突然变得不那么聪明了。

那么,现代硬件预取器到底是做什么的呢?它们会被“非本地”指针绊倒吗?

【问题讨论】:

  • 我可能听起来很愚蠢,但什么是非本地指针?
  • 在这个问题中,“本机”指针应该是一个字面意义上的保存内存地址的值。 0x1234 将指向0x1234 的内存。 “非本机”指针是以间接方式引用内存的值。在这种情况下,0x1234 可能指的是some_array[0x1234] 的内存,或者更复杂的东西,例如array = some_map[0x1234>>8]; pointer = array[0x1234&0xff]

标签: c++ c optimization prefetch cpu-cache


【解决方案1】:

链接数据结构 (LDS) 预取仍然是计算机体系结构中的一个已知问题。我不熟悉任何真正做到这一点的现代 CPU,但理论上这是可能的。多年来,有几篇学术论文提出了一些变化:

  1. 一种专用硬件,可以检测提取的缓存行中类似地址的值,并向这些地址发出预取。
  2. 一种编译器辅助技术,编译器识别数据结构依赖关系并插入软件预取或其他提示。

这两种方法都可能会受到您的技术的影响(第一种方法会变得无用,如果编译器足够聪明,第二种方法可能会起作用)。

当然,你必须在这样的机器上实际运行,所以这只是理论上的,如果它适合你,你不应该改变你的做法,但这表明分析应该是每个微的特定的-架构和系统,以及在一种情况下对您有帮助的东西,在另一种情况下可能效率较低。
一般来说 - 不要只相信 CPU 会做或不做一些优化(除非有文档记录),请始终检查您是否获得了预期的行为。

顺便说一句,请注意,即使硬件看到内存的内容,它仍然在虚拟地址空间中 - 无论如何,硬件必须对物理地址进行某种转换才能使用它,所以在某种意义上不必有任何额外的开销。

一些参考书目:

【讨论】:

  • 接受这一点,因为它最直接地回答了手头的问题:不,目前没有已知的 CPU 基于链接数据进行预取。
  • 好吧,如果我完成了我的论文,我会看看能不能把它卖给 Intel/AMD/..,也许有一天会有:)
【解决方案2】:

硬件预取器看不到指针,它看到的是内存地址。它不关心地址来自哪里,也不关心它在您编写的 C++ 程序中的类型。它只是查看 CPU 被告知从哪个地址读取或写入。

所以不,对数组进行索引不会是 CPU 从未遇到过的可怕新事物。

【讨论】:

  • 没错。在尝试了解 CPU 的功能时,不要考虑类型
  • @MarcClaesen:好吧,为了公平起见,即使在 CPU 表示方面,内存地址的表示方式(64 位上的 8 个字节)和“已知”的偏移量之间也存在差异" 表示地址(如果足够的话,可能只有 2 个字节)。例如,提议的“新奇”优化在看起来像 L1 缓存中的内存地址的任何地方预取内存似乎完全合法,并且会被“内存节省”偏移量所破坏。
  • @jalf:当然它看不到类型。但是看到内存地址了吗? 什么时候它“看到”一个内存地址?什么时候入户口?什么时候实际使用作为内存地址?
  • @MSalters,很久以前就首次提出了,但这个想法远未结束。 SW 预取无法帮助您提前运行链接的数据结构,因为您仍然不知道地址。在提取依赖的情况下,流水线也无济于事。总的来说,这仍然是一个悬而未决的问题。
  • @MSalters - 数据相关的预取可以在较低的缓存级别上实现,甚至在内存控制器中(并“猜测”物理转换或在页面边界内工作) - 这比一直进行要快得多直到 Mem 单元并发出下一次提取。无论如何,这不是重点——我认为假设没有 CPU 会这样做有点冒险,仅此而已。
猜你喜欢
  • 2011-10-13
  • 2010-12-17
  • 1970-01-01
  • 2019-09-18
  • 2011-01-10
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
相关资源
最近更新 更多