2009-08-12 84 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不會等待或阻塞,它只是讓處理器開始獲取指定內存位置的數據。

相關問題