Assembly 如何从内存加载值而不污染缓存?

Assembly 如何从内存加载值而不污染缓存?,assembly,caching,x86,Assembly,Caching,X86,我想在不污染缓存的情况下读取内存位置。我在x86Linux机器上工作。我尝试使用MOVNTDQA汇编程序指令: asm("movntdqa %[source], %[dest] \n\t" : [dest] "=x" (my_var) : [source] "m" (my_mem[0]) : "memory"); my_mem是一个整数*分配给new,my_var是一个整数 这种方法有两个问题: 代码可以编译,但运行时出现“非法指令”错误。你知道为什么吗 我不确定是什么类型的内

我想在不污染缓存的情况下读取内存位置。我在x86Linux机器上工作。我尝试使用MOVNTDQA汇编程序指令:

  asm("movntdqa %[source], %[dest] \n\t"
      : [dest] "=x" (my_var) : [source] "m" (my_mem[0]) : "memory");
my_mem是一个整数*分配给new,my_var是一个整数

这种方法有两个问题:

  • 代码可以编译,但运行时出现“非法指令”错误。你知道为什么吗
  • 我不确定是什么类型的内存分配与新的。我认为WB。根据文档,MOVNTDQA指令仅适用于USWC内存类型。我怎样才能知道我使用的是哪种内存类型
  • 总而言之,我的问题是:

    如何读取内存位置而不污染X86机器上的缓存?我的方法是正确的方向吗?它能被固定下来吗


    谢谢。

    MOVNTDQA仅适用于SSE

    为什么要避免使用缓存?CPU通常非常擅长决定何时从缓存中删除什么。如果确实需要,一种方法是将您正在读取的内存区域的别名映射到您的地址空间中,禁用缓存并从那里读取


    如果您试图实现的目标实际上是将代码对另一个函数的工作集的影响降到最低,则可以通过发出适当的预取和失效指令来实现。

    以%%xmm为目标(从内存加载)的movntdqa指令的问题该insn仅适用于SSE4.1及更高版本。这意味着到目前为止,新的Core2(45纳米)或i7才刚刚出现。另一种方法(将数据存储到内存)在早期的SSE版本中可用

    对于该指令,处理器将数据移动到一个非常小的读取缓冲区中(Intel没有指定确切的大小,但假设它在16字节的范围内),在该缓冲区中数据随时可用,但在其他一些加载后会被踢出

    而且它不会污染其他缓存,因此如果您有流式数据,您的方法是可行的

    记住,之后你需要使用sfence insn

    预取有两种变体:预取T0(预取所有缓存中的数据)和预取(预取非时态数据)。通常,在所有缓存中进行预取是正确的做法,对于流式数据循环,如果后续使用流式指令,后者会更好


    您将它与您希望在不久的将来使用的对象的地址一起使用,如果您有一个循环,通常会提前一些迭代。预取insn不会等待或阻塞,它只会使处理器开始在指定的内存位置获取数据。

    这个问题与此相关吗?我想这是相关的:),但不幸的是,这个问题/答案并不能帮助我回答这个问题。哦,还有一件事:我甚至不确定是否有可能做到这一点:-/我当然希望是这样。我在一个进程上有两个核心-其中一个严重使用缓存,另一个优先级较低,因此,我试图减少它的缓存使用。在这台机器上,二级缓存对于两个核心是相互的——因此我想做的是将内存直接加载到一级或寄存器(在低优先级程序中)。你能详细说明一下在这种情况下使用预取和失效指令对我有什么帮助吗?非常感谢。我的想法是安排低优先级进程在处理完缓存线后立即显式地清除缓存线,这样就可以比CPU的缓存管理策略允许的时间更早地重新填充缓存线,也许还可以安排高优先级进程在特别昂贵的部分发布预取。不过,不确定这种方法对您的场景有多大帮助。@moonshadow:处理器并不总是擅长决定缓存什么。这就是为什么有movntdqa指令的明确原因。它用于流式传输数据,一旦使用,就再也不会接触(至少不会太快;-)。对于辅助线程,如果有另一个线程可用,这可能是可行的,否则就不能完全使用它——我想到了超线程。但在大多数情况下,如果两个线程执行全部工作并使用显式预取指令,您将获得更好的结果。