2009-08-12 86 views
15

我想读取内存位置而不污染缓存。我正在使用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。

我有两个问题,这种方法:

  1. 代码编译,但在运行它时我收到“非法指令”的错误。任何想法为什么?
  2. 我不确定什么类型的内存分配新的。我会假设WB。根据文档,MOVNTDQA指令将只能使用USWC存储器类型。我怎么知道我正在使用哪种内存类型?

总之,我的问题是:

我怎么能不污染的X86机器上的缓存读取一个存储器位置?我的方法是否朝着正确的方向发展,是否可以固定下来?

谢谢。

+0

与此问题相关吗? HTTP://计算器。COM /问题/ 851286 /如何使用的,movntdqa到避免缓存污染 – sharptooth 2009-08-12 10:57:11

+1

我想这是相关的:),但不幸的是,这个问题/答案并不能帮助我这个问题。 – Anna 2009-08-12 11:04:49

+0

哦,还有一件事:我不确定甚至有可能做到这一点: - /我当然希望它是。 – Anna 2009-08-12 11:06:42

回答

0

MOVNTDQA仅适用于SSE。

你为什么试图避免使用缓存? CPU在决定什么时候退出缓存时通常相当不错。如果真的需要,一种方法是安排您正在读取的内存区域的别名映射到您的地址空间,禁用缓存并从此处读取。

如果你要实现的目标实际上是尽量减少您的代码在当时的缓存正在举行另一功能的工作集的影响,这应该是通过发出适当的预取可行的,无效的指令。

+0

我在一个进程上有两个内核 - 其中一个严重使用缓存,另一个优先级较低,因此我试图减少其缓存使用率。 在这个机器上,L2缓存是相互的两个核心 - 所以我想这样做是对的存储器,可直接加载到L1,或寄存器(在低优先级程序)。 能否请您阐述一下如何使用预取和无效指令可以帮助我在这种情况下? 非常感谢。 – Anna 2009-08-12 11:40:40

+0

我的想法是,为低优先级的进程,尽快明确地踢了它的高速缓存行安排,因为它是与他们做,从而使他们能够重新填充比CPU的缓存管理政策迟早会以其他方式允许,或许安排的在特别昂贵的部分中发布预取的高优先级进程。不知道这种方法对你的情况有多大帮助。 – moonshadow 2009-08-12 11:47:03

+3

@moonshadow:处理器并不总是擅长决定缓存什么。这就是为什么有movntdqa指令的明确原因。它用于流数据,一旦使用,再也不会触及(至少不会太早;-))。 作为一个辅助线程,这可能是可行的,如果有另一个线程可用,这不能完全以其他方式使用 - 超线程想到的。但在大多数情况下,使用两个线程完成工作并使用显式预取指令,您将获得更好的结果。 – hirschhornsalz 2009-08-15 13:03:06

7

与%% XMM作为靶(装载从存储器)的movntdqa指令的问题是,该insn仅适用于SSE4.1和上。这意味着目前只有更新的Core 2(45纳米)或i7。另一种方式(将数据存储到内存)在早期的SSE版本中可用。

对于这条指令,处理器将数据移入一小部分非常少的读缓冲区(英特尔没有指定确切的大小,但假设它在16字节的范围内),在那里它很容易获得,但在其他一些负载后会被踢出去。

而且不污染其它高速缓存,所以如果你有数据流,你的做法是可行的。

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

预取存在两种变体:prefetcht0(所有高速缓存预取的数据)和prefetchnt(预取非暂时数据)。通常在所有缓存中进行预取是正确的,对于流式数据循环而言,如果您随后使用流式指令,后者会更好。

你你想要的,如果你有一个循环前进,在不久的将来使用,通常是一些重复的对象的地址使用它。预取insn不会等待或阻塞,它只是让处理器开始获取指定内存位置的数据。

相关问题