通過立即數常量(操作碼中的常量)或索引常量(通過ldc
指令訪問)訪問的常量變量由(bank,offset)對訪問,而不是通過地址訪問。這些讀取通過直接常量和索引常量高速緩存。在一些芯片上,這些是相同的緩存。不斷訪問的示例如下:
// immediate constant
ADD r0, r1, c[bank][offset]
// r1 has packed version of bank, offset
LDC r0, r1
通過cc2.0及以上版本的參數,您將看到直接不斷的訪問。
常量訪問經歷了恆定的內存層次結構,最終導致全局地址可以在系統內存或設備內存中。
如果將常量變量設置爲全局指針,則將通過數據層次結構讀取數據。
如果您定義了一個const變量,編譯器可以選擇將只讀數據放入存儲區/偏移量或地址中。
如果您查看SASS(nvdisasm或工具),您將看到LD
說明。根據芯片的不同,這些數據可能會緩存在L1/Tex緩存中,然後是L2緩存。
SHARED
LDS/STS/ATOMS -> shared memory
GENERIC
LD/ST (generic to shared) -> shared memory
LD/ST (generic to global) -> L1/TEX -> L2
LD/ST (generic to local) -> L1/TEX -> L2
LOCAL
LDL/STL (local) -> L1/TEX -> L2
GLOBAL
LDG/STG (global) -> TEX -> L2
INDEXED CONSTANT
LDC -> indexed constant cache -> ...-> L2
L2未命中可以進入設備內存或固定系統內存。
如果您提到常量變量很可能會通過立即常量(假設合理常量大小的最佳性能)訪問,並且解除引用的指針將導致全局內存訪問。
在GK110上LDG
指令被緩存在紋理緩存中。
On Maxwell LDG.CI
指令緩存在紋理緩存中。將LDG.CA
操作緩存在紋理緩存(GM20x)中。所有其他LDG
訪問都會經過紋理緩存,但不會超出warp指令的生命週期。
我的方法可能並不是最好的,那麼我不要把全局讀取放在一個常量上,或者通過不斷的內存層次結構。 – James