快速使缓存失效

4

除了迭代一个大的虚拟数组之外,C++中是否有一种快速使处理器的L2缓存失效的方法?


你为什么需要那个? - Vilx-
3个回答

1

我假设这是为了性能测试,您想要消除运行之间的缓存效应。

在这种情况下,您需要知道以下信息才能有效地执行此操作:

  1. L2缓存的分配大小
  2. L2缓存中有多少个分配

然后,基本上就是触摸内存,距离每个其他的allocation_size字节,直到完全刷新缓存。

上下文切换也经常使缓存无效 - 等待一毫秒可能会更快,如果操作系统将您换入和换出,则很可能会清除缓存。


这是一种可移植的方法。可能有一种方法可以转到汇编语言并在那里实现它。有些处理器甚至可能有一个单一的指令来完成它。 - Omnifarious
这是用于非常高分辨率计时的,运行长度约为50纳秒,因此我希望使用最快的方法。 - Mark
2
如果您可以进入内核模式,您可以发出WBINVD,这将导致所有内部缓存被刷新。只需注意该指令是在缓存很小的时候设计的,因此完成时间(相对而言)较长,一般不推荐使用。(参见http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-07/msg09421.html) - Anon.
我将采用上一个评论中的答案,因为按缓存行迭代是我之前已经在做的。 - Mark

1

另一个可能的解决方案是确保每次运行对缓存内容敏感的东西时,使用完全不同的内存部分。然后,这些内存位将不会在缓存中,有效地刷新了缓存。

当然,这对指令缓存来说可能不是一个很容易管理的解决方案,只适用于数据缓存,即使如此,处理堆栈也会很棘手。

我想不出这种方法可靠地适用于TLB缓存,如果您关心的话。

这种方法的另一个问题是可能仍然存在脏缓存行,代码的后续运行将产生将它们刷新到主存储器的成本。


-2

你想在VC++中使用内存栅栏:

void SThreadUtil::synchronizeCache()
{
    _mm_mfence();
}

抱歉,刷新应该使用_mm_clflush


2
你确定那会使缓存失效吗?内存栅栏只是保证了总线上的内存操作顺序到主内存的顺序,对吗? - Omnifarious
_mm_cflush带有一个参数,所以OP将不得不猜测可能会干扰的缓存内容,然后确保将它们全部刷新。 - Omnifarious
看起来_mm_clflush一次只会刷新一个缓存行 - http://msdn.microsoft.com/en-us/library/ba08y07y.aspx - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接