有没有办法在不触及x86 CPU下的L1 / L2 / L3缓存的情况下写入/读取内存?
是否完全由硬件管理的x86 CPU缓存?
编辑:我想这样做是因为我想对内存的速度进行采样,看看内存的性能是否会降低。
答案 0 :(得分:13)
CPU确实在硬件中管理自己的缓存,但x86为您提供了一些影响此管理的方法。
要在不使用缓存的情况下访问内存,您可以:
使用x86非临时说明,它们意味着要告诉CPU您再也不会重复使用这些数据了,所以没有必要将它保留在缓存。 x86中的这些指令通常称为movnt *(根据数据类型具有后缀,例如用于将正常整数加载到通用寄存器的movnti)。还有用于流加载/存储的指令,这些指令也使用类似的技术但更适合于高BW流(当您连续加载整行时)。 要使用它们,要么在内联汇编中对它们进行编码,要么使用编译器提供的内在函数,其中大多数都称之为_mm_stream _ *
将特定区域的内存类型更改为不可缓存。既然你说你不想禁用所有缓存(理所当然,因为那也包括代码,堆栈,页面地图等等),你可以定义基准数据的特定区域 - set使用MTRR(内存类型范围寄存器)以不可缓存的方式驻留。有几种方法,您需要阅读一些文档。
最后一个选项是正常获取行,这意味着它最初会被缓存,但是然后使用专用clflush指令强制它清除所有缓存级别(如果要刷新,则强制清除所有缓存级别)整个缓存)。确保对这些操作进行适当的操作,以确保他们能够完成这些操作(当然,不要将其作为延迟的一部分进行测量)。
话虽如此,如果你想做所有这些只是为了记忆你的内存,你可能会得到不好的结果,因为大多数CPU处理非时间或不可缓存的访问"效率低下"。如果您在强制读取来自内存之后,最好通过依次访问大到不适合任何高速缓存的数据集来操纵高速缓存LRU来实现。这将使大多数LRU方案(不是全部!)首先丢弃最旧的行,所以下次你回绕时,它们必须来自内存。
请注意,要使其工作,您需要确保您的硬件预取器没有帮助(并且意外地覆盖了您要测量的延迟) - 要么禁用它,要么使访问步幅足够远以使其无效。
答案 1 :(得分:6)
Leeor preety列出了最适合您任务的“专业”解决方案。我将尝试添加另一个可以实现相同结果的提议,并且可以使用简单的代码在纯C中编写。这个想法是在 HPCC Challenge 基准测试中创建类似于“全局随机访问”的内核。
内核的想法是随机跳过一个巨大的数组的8B值,这些值通常是物理内存大小的1/2(所以如果你有16 GB的内存,你需要一个8GB阵列导致8B的1G元素。对于每次跳转,您可以读取,写入或RMW目标位置。
这很可能测量RAM延迟,因为随机跳过RAM 会使缓存效率非常低。您将获得极低的缓存命中率,如果您对阵列进行了足够的操作,您将能够测量内存的实际性能。由于没有可检测的模式,此方法使预取非常无效。
您需要考虑以下事项: