より高速なバージョン:
__global__ void convAgB(double *a, double *b, double *c, int sa, int sb)
{
int i = (threadIdx.x + blockIdx.x * blockDim.x);
int idT = threadIdx.x;
int out,j;
__shared__ double c_local [512];
c_local[idT] = c[i];
out = (i > sa) ? sa : i + 1;
j = (i > sb) ? i - sb + 1 : 1;
for(; j < out; j++)
{
if(c_local[idT] > a[j] + b[i-j])
c_local[idT] = a[j] + b[i-j];
}
c[i] = c_local[idT];
}
**Benckmark:**
Size A Size B Size C Time (s)
1000 1000 2000 0.0008
10k 10k 20k 0.0051
100k 100k 200k 0.3436
1M 1M 1M 43,327
古いバージョン、1000 から 100000 の間のサイズの場合、この素朴なバージョンでテストしました:
__global__ void convAgB(double *a, double *b, double *c, int sa, int sb)
{
int size = sa+sb;
int idT = (threadIdx.x + blockIdx.x * blockDim.x);
int out,j;
for(int i = idT; i < size; i += blockDim.x * gridDim.x)
{
if(i > sa) out = sa;
else out = i + 1;
if(i > sb) j = i - sb + 1;
else j = 1;
for(; j < out; j++)
{
if(c[i] > a[j] + b[i-j])
c[i] = a[j] + b[i-j];
}
}
}
配列にいくつかのランダムな倍精度数と 999999 (テスト用) を入力a
しb
ましc
た。c
関数を使用して(変更なしで)(CPU内の)配列を検証しました。
また、内側のループの内側から条件を削除したので、一度だけテストします。
100% 確信があるわけではありませんが、次の変更は理にかなっていると思います。を持っていたのでi - j >= 0
、これは と同じで、これは、このブロック 'X' に入らないとi >= j
すぐに(j++ から) ということを意味します。j > i
if(c[i] > a[j] + b[i-j])
c[i] = a[j] + b[i-j];
したがって、変数out
でループ条件 ifを計算しましたi > sa
。これは、ループが終了するときにループが終了することをj == sa
意味i < sa
しi + 1
ますi >= j
。
他の条件は、i - j < size(b)
ブロック 'X' の実行を開始することを意味します。i > size(b) + 1
j
j
if(i > sb) j = i - sb + 1;
else j = 1;
このバージョンを実際のデータ配列でテストできるかどうかを確認し、フィードバックをお寄せください。また、改善点は大歓迎です。
編集:新しい最適化を実装できますが、これは大きな違いはありません。
if(c[i] > a[j] + b[i-j])
c[i] = a[j] + b[i-j];
次の方法でifを排除できます。
double add;
...
for(; j < out; j++)
{
add = a[j] + b[i-j];
c[i] = (c[i] < add) * c[i] + (add <= c[i]) * add;
}
持つ:
if(a > b) c = b;
else c = a;
c = (a < b) * a + (b <= a) * b と同じです。
a > b の場合、c = 0 * a + 1 * b; => c = b; a <= b の場合、c = 1*a + 0 *b; => c = a;
**Benckmark:**
Size A Size B Size C Time (s)
1000 1000 2000 0.0013
10k 10k 20k 0.0051
100k 100k 200k 0.4436
1M 1M 1M 47,327
CPU から GPU へのコピー、カーネルの実行、GPU から CPU へのコピーの時間を測定しています。
GPU Specifications
Device Tesla C2050
CUDA Capability Major/Minor 2.0
Global Memory 2687 MB
Cores 448 CUDA Cores
Warp size 32