我想在不污染缓存的情况下读取内存位置。我正在X86 Linux机器上工作。我尝试使用MOVNTDQA汇编程序指令:
asm("movntdqa %[source], %[dest] \n\t"
: [dest] "=x" (my_var) : [source] "m" (my_mem[0]) : "memory");my_mem是一个int*,my_var是一个int。
我对这种方法有两个问题:
总之,我的问题是:
如何在不污染X86机器上的缓存的情况下读取内存位置?我的方法是正确的方向,它能被固定的工作吗?
谢谢。
发布于 2009-08-15 13:02:44
以%xmm作为目标(从内存加载)的movntdqa指令的问题是,这个insn只能在SSE4.1和on中使用。这意味着更新的核心2 (45 nm)或i7仅到目前为止。另一方面(将数据存储到内存)可以在早期的SSE版本中使用。
对于这个指令,处理器将数据移动到一个非常小的极小的读取缓冲区中(Intel没有指定确切的大小,但假设它在16字节的范围内),在这里它很容易获得,但在其他几个负载后被踢出。
而且它不会污染其他缓存,所以如果您有流数据,您的方法是可行的。
记住,你需要在事后使用篱笆。
预取存在于两个变体中: prefetcht0 (所有缓存中的预取数据)和预取(预取非时态数据)。通常,预取所有缓存是正确的做法,对于流数据循环,如果您随后使用流指令,后者会更好。
您将它与您希望在不久的将来使用的对象的地址一起使用,如果您有一个循环,通常会在前面进行一些迭代。预取insn不等待或阻止,它只是使处理器开始在指定的内存位置获取数据。
发布于 2009-08-12 11:32:23
MOVNTDQA只适用于SSE。
为什么要避免使用缓存?CPU通常会很好地决定何时退出缓存。如果确实需要这样做,一种方法是将正在读取的内存区域的别名映射到您的地址空间,并禁用缓存并从中读取。
如果您想要实现的实际上是最小化代码对另一个函数在缓存中的工作集的影响,则应该通过发出适当的预取和无效指令来做到这一点。
https://stackoverflow.com/questions/1265469
复制相似问题