assembly - 如何在不污染缓存的情况下从内存加载值?

标签 assembly caching x86

我想在不污染缓存的情况下读取内存位置。我正在 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。

我对这种方法有两个问题:
  • 代码可以编译,但在运行时出现“非法指令”错误。任何想法为什么?
  • 我不确定新分配的内存类型。我会假设 WB。根据文档,MOVNTDQA 指令仅适用于 USWC 内存类型。我如何知道我正在使用哪种内存类型?

  • 总而言之,我的问题是:

    如何在不污染 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/

    相关文章:

    c - 如何告诉 GCC 为实模式生成 16 位代码

    assembly - INT 13h,获取最后操作的状态

    caching - 强制(或高度鼓励)浏览器直接从缓存中加载网络字体

    windows - x86 - Windows 是否将 dll 映射到不同进程中的同一物理页面?

    assembly - 是否可以将汇编语言转换为 LLVM IR,对其进行优化,然后将其重新编译为不同的体系结构?

    exception - RISC-V 从带有压缩指令的异常处理程序返回

    php - 在 php 脚本中使用缓存

    firefox - 为什么请求缓存的过期日期是过去的日期?

    c++ - SSE 优化的 64 位整数模拟

    c - 了解 ATT 汇编语言