私のカーネルはfloat
、以下のランダム アクセス パターンでサイズ 8 x 8 の配列を使用します。
// 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: ターゲット アーキテクチャは Fermi と Kepler です。