"non-native"指针会损害缓存性能吗?
Can "non-native" pointers hurt cache performance?
我所知,硬件预取器至少会检测并获取内存中的恒定步伐。此外,它可以监视数据访问模式,无论这真正意味着什么。这让我想知道,硬件预取器是否曾经根据存储在内存中的实际数据做出决定,或者纯粹基于程序所表现出的行为?
我问的原因是因为我会偶尔使用"非本机"指针作为指针。一个简单的例子是预先分配的东西数组,以及索引这个数组而不是指针的小整数。如果我需要存储大量这样的"指针",节省的内存可以快速增加,从而通过使用更少的内存间接提高缓存性能。
但据我所知,这可能会干扰硬件预取程序的工作方式。要不!
我当然可以想象,无论现实与否,一个预取单元,它检查进入 L1 缓存的缓存行以获取本机指针地址并开始将它们提取到 L2 或类似的东西中。在这种情况下,我保存记忆的聪明伎俩突然变得不那么聪明了。
那么,现代硬件预取器到底是做什么的呢?它们会被"非本地"指针绊倒吗?
硬件预取程序看不到指针,它看到内存地址。它不在乎地址来自哪里,也不在乎它在您编写的C++程序中具有什么类型。它只是查看 CPU 被告知读取或写入的地址。
所以不,索引到数组中不会是 CPU 以前从未遇到过的可怕新事物。
链接数据结构(LDS)预取仍然是计算机体系结构中的一个已知问题。我不熟悉任何实际做到这一点的现代 CPU,但理论上这是可能的。多年来,有几篇学术论文提出了一些变化:
- 专用硬件,可以检测提取的缓存行中的类似地址的值,并向这些地址发出预取。
- 一种编译器辅助技术,编译器识别数据结构依赖关系并插入 SW 预取或其他提示。
这两种方法都可能受到您的技术的影响(第一种方法将变得无用,如果编译器足够聪明,第二种方法可能会起作用)。
当然,你必须在这样的机器上运行,所以它只是理论上的,如果它对你来说工作正常,你不应该改变你的做法,但它表明分析应该是特定于每个微架构和系统的,在一种情况下帮助你的东西,在另一种情况下可能效率较低。
一般来说 - 不要只相信 CPU 做或不做一些优化(除非它被记录下来),总是检查你得到预期的行为。
顺便说一下,请注意,即使硬件看到内存的内容,它仍然在虚拟地址空间中 - 硬件无论如何都必须对物理地址进行某种转换才能使用它,因此从某种意义上说,不必有任何额外的开销。
一些参考书目:
- 针对动态数据结构的编译器定向内容感知预取
- 链接数据结构的基于依赖关系的预取
- 引导式区域预取:一种协作式硬件/软件方法
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- OpenMP阵列性能较差
- 递归列出所有目录中的C++与Python与Ruby的性能
- 大小相等但成员数量不同的结构之间的性能差异
- cmake更新缓存的变量
- 为什么constexpr的性能比正常表达式差
- 试图对缓存进行跨步测试,但程序并没有结束
- 在类中使用随机生成器时出现性能问题
- 迭代时的性能(缓存未命中)
- 高速缓存行检索和在大型数据结构上的性能
- "non-native"指针会损害缓存性能吗?
- 如何使用缓存技术提高性能
- OOP是否鼓励良好的缓存,从而提高性能
- 指针在内存缓存方面的性能
- 向量,矩阵和四元数的缓存性能
- 缓存位置性能
- C++缓存性能奇怪的行为
- C++池分配器与静态分配,缓存性能
- 2bit位域数组对性能和缓存效率的影响
- 用于缓存和内存总线性能的工具或代码