我想在不污染缓存的情况下读取内存位置。我正在 X86 Linux 机器上工作。我尝试使用 MOVNTDQA 汇编指令:
asm("movntdqa %[source], %[dest] \n\t"
: [dest] "=x" (my_var) : [source] "m" (my_mem[0]) : "memory");
my_mem 是一个用 new 分配的 int*,my_var 是一个 int。
我对这种方法有两个问题:
总而言之,我的问题是:
如何在不污染 X86 机器上的缓存的情况下读取内存位置?我的方法是否朝着正确的方向发展,是否可以修复?
谢谢。
最佳答案
以 %%xmm 为目标(从内存加载)的 movntdqa 指令的问题在于,此 insn 仅适用于 SSE4.1 及更高版本。这意味着目前只有更新的 Core 2 (45 nm) 或 i7。另一种方式(将数据存储到内存)在早期的 SSE 版本中可用。
对于这条指令,处理器将数据移动到非常少的读取缓冲区中的一个很小的缓冲区中(英特尔没有指定确切的大小,但假设它在 16 字节的范围内),在那里它随时可用,但被踢出在其他一些负载之后。
并且它不会污染其他缓存,因此如果您有流数据,您的方法是可行的。
记住,之后你需要使用一个sfence insn。
预取存在两种变体:prefetcht0(预取所有缓存中的数据)和 prefetchnt(预取非临时数据)。通常在所有缓存中预取是正确的做法,对于流数据循环,如果您随后使用流指令,后者会更好。
您将它与您想在不久的将来使用的对象的地址一起使用,如果您有循环,通常会提前一些迭代。 prefetch insn 不会等待或阻塞,它只是让处理器开始在指定的内存位置获取数据。
关于assembly - 如何在不污染缓存的情况下从内存加载值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1265469/