我的內核使用float
大小爲8乘8的數組,其隨機訪問模式如下所示。從CUDA內核中隨機訪問小常量數組的工作原理
// inds - big array of indices in range 0,...,7
// flts - 8 by 8 array of floats
// kernel essentially processes large 2D array by looping through slow coordinate
// and having block/thread parallelization of fast coordinate.
__global__ void kernel (int const* inds, float const* flt, ...)
{
int idx = threadIdx.x + blockDim.x * blockIdx.x; // Global fast coordinate
int idy; // Global slow coordinate
int sx = gridDim.x * blockDim.x; // Stride of fast coordinate
for (idy = 0; idy < 10000; idy++) // Slow coordinate loop
{
int id = idx + idy * sx; // Global coordinate in 2D array
int ind = inds[id]; // Index of random access to small array
float f0 = flt[ind * 8 + 0];
...
float f7 = flt[ind * 8 + 7];
NEXT I HAVE SOME ALGEBRAIC FORMULAS THAT USE f0, ..., f7
}
}
什麼是訪問flt
數組的最佳方式?
- 請勿通過
flt
,請使用__const__
內存。我不知道當不同的線程訪問不同的數據時,const內存有多快。 - 如上使用。因爲線程訪問不同的數據,所以不使用負載均勻。它會因爲緩存而變快嗎?
- 複製到共享內存並使用共享內存數組。
- 使用紋理。從未使用過的紋理......這種方法可以快嗎?
對於共享存儲器,它可能是更好的轉置flt
陣列,即訪問這種方式,以避免存儲體衝突:
float fj = flt_shared[j * 8 + ind]; // where j = 0, ..., 7
PS:目標架構是費米和開普勒。
那麼,你有沒有嘗試過使用'__constant__'或'__shared__'內存和計時內核?在內核中多次訪問'flt'。我認爲'__shared__'記憶會給你最好的表現。 – sgarizvi 2013-03-02 05:41:46
'__constant__'只有在warp中的所有線程都可以訪問相同的值時纔是一個不錯的選擇。恕我直言,這裏最好的選擇是使用包含轉置數據的共享內存。請指定您的目標計算架構,它可能會產生影響。 – RoBiK 2013-03-02 10:19:50
到目前爲止,我只實現了'inds'數組中所有值都爲0的情況,所以我沒有隨機訪問,我使用'__const__'而不是'flt'參數。順便說一句,在這種情況下,如果使用'-dlcm = cg'選項編譯我的內核,它的工作速度會更快。現在我需要將我的內核擴展到一般情況。 – user2052436 2013-03-03 02:43:14