在共享內存中存儲常量值有什麼好處嗎?例如:共享內存和常量
A[tid] = CONSTANT * B[tid]
,
其中A和B是數組,常數是恆定值例如4.並且tid是線程索引(數組元素=單線程)。
每個線程必須讀取值CONSTANT
,所以共享內存應該是有用的,對吧?
我認爲它的工作原理: 從全局內存中讀取消耗大量時間,所以從全局內存中讀取一次共享內存的constatnt值,然後線程可以快速讀取它。因爲有很多線程(常數值必須被多次讀取),共享內存應該加快速度。
在共享內存中存儲常量值有什麼好處嗎?例如:共享內存和常量
A[tid] = CONSTANT * B[tid]
,
其中A和B是數組,常數是恆定值例如4.並且tid是線程索引(數組元素=單線程)。
每個線程必須讀取值CONSTANT
,所以共享內存應該是有用的,對吧?
我認爲它的工作原理: 從全局內存中讀取消耗大量時間,所以從全局內存中讀取一次共享內存的constatnt值,然後線程可以快速讀取它。因爲有很多線程(常數值必須被多次讀取),共享內存應該加快速度。
某些CPU指令集(如x86)支持將全尺寸常量存儲爲與操作碼本身交錯的操作數。在這種情況下,常量顯然會與CPU正在運行的其他指令流一起讀入,並且似乎不太可能將其存儲在其他任何位置的任何其他位置的速度更快。
其他體系結構(如ARM)支持在操作碼內存儲小常量和移位值。程序中通常需要的大多數常量可以表示爲小常數加上移位值,因此可以直接存儲在操作碼中。
我不知道SASS(NVIDIA GPU的本機指令集)是否支持這種「嵌入」常量。
儘管如此,如果將常量存儲在共享內存中,則需要引用該常量,並且引用本身將是常量,或者將從常量(例如基址)派生。
此外,還有一個指定爲常量的值的緩存。調用內核之前,可以通過在常量內存中設置值來利用此緩存。
此外,考慮首先在共享內存中設置常量的開銷。共享內存中的值只能通過塊中的線程共享,因此每個塊必須重新設置常量。因爲線程運行在32個被稱爲warps的組中,所以內核會在設置常量時綁定32個線程,每次在新塊上開始處理。總結一下,我認爲最好讓編譯器處理單個常量(比如你的例子中的常量),並使用常量內存來存儲你可能擁有的任何常量數組。
恆定內存空間被高速緩存,並且具有很高的讀取性能。所以我懷疑將存儲在共享內存中會有很大的性能差異。
各種GPU指令集提供了在一些指令中編碼的立即值,無論是用於整數指令還是浮點指令。編譯器將盡可能利用編譯時常量。如果常量不能嵌入到指令中,編譯器可以將它放入一個常量存儲區,並且可以通過常量高速緩存來緩存該數據,該常量高速緩存具有廣播功能,可以同時爲相同常數的所有常量提供所有trhead 。所以對於單個常量,人們可以簡單地依靠編譯器。 – njuffa