如何将一些内存范围标记为不可缓存的C ++?

时间:2012-03-03 06:35:50

标签: c++ caching

我正在这里阅读CPU缓存上的维基百科:http://en.wikipedia.org/wiki/CPU_cache#Replacement_Policies

  

通过避免缓存很少重新访问的内存区域,将某些内存范围标记为不可缓存可以提高性能。这样可以避免将内容加载到缓存中的开销,而无需重复使用。

现在,我一直在阅读和学习如何编写具有更好缓存性能的程序(一般考虑因素,通常不是特定于C ++),但我不知道高级代码可以明确地与CPU缓存行为进行交互。所以我的问题是,有没有办法用C ++中的那篇文章引用我所引用的内容?

此外,我很欣赏有关如何在C ++中提高缓存性能的资源,即使它们不使用任何直接处理CPU缓存的函数。例如,我想知道是否使用过多的间接层(例如,指针容器的指针容器)会损坏缓存性能。

4 个答案:

答案 0 :(得分:6)

在Windows上,您可以使用VirtualProtect(ptr, length, PAGE_NOCACHE, &oldFlags)设置内存的缓存行为以避免缓存。

关于太多的间接性:是的,如果您经常访问不同的内存(通常会发生这种情况),它们可能会损坏缓存性能。但是,重要的是要注意,如果您始终取消引用相同的组,例如8个内存块,只有第9个块不同,然后它通常不会产生影响,因为在第一次访问后将缓存8个块。

答案 1 :(得分:5)

优化缓存访问的经验法则是:群集一起加载并存储到同一地址。例如,以下代码:

for (size_t i=0; i<A.size(); ++i)
  B[i] = func1(A[i]);

for (size_t i=0; i<A.size(); ++i)
  C[i] = func2(A[i]);

可以进行优化以更有效地访问缓存:

for (size_t i=0; i<A.size(); ++i) {
  B[i] = func1(A[i]); // A[i] is fetched to the cache
  C[i] = func2(A[i]); // Good chance that A[i] remains in the cache
}

现代CPU非常擅长使用循环中的常规模式预测内存访问,并且能够预取内存以进行缓存并加快执行速度。所以另一个经验法则是:更喜欢使用std :: vector和std :: array而不是其他容器

答案 2 :(得分:5)

某些平台支持非临时加载和绕过缓存的存储。这可以避免丢失之前缓存中的任何内容。它们通常不能直接用于更高级别的语言,您必须编写自己的汇编代码。但由于即使缓存的存​​在是特定于平台的,控制缓存使用的方式的存在同样是特定于平台的。 SSE4确实包括non-temporal loads

作为程序员,通常处理Windows以外的x86平台,this article on x86 and x86-64 GCC intrinsics可能是最有用的。

答案 3 :(得分:4)