これは、CUDA プログラムと並行開発での 2 回目の試みです。
内積が2つの配列になる理由を見つけようとしています。
例:
与えられた
A = [1 2 3]
B = [4 5 6]
C[0] = (1)(4) + (1)(5) + (1)(6)
C[1] = (2)(4) + (2)(5) + (2)(6)
C[2] = (3)(4) + (3)(5) + (3)(6)
2 つの配列 A と B を初期化し、範囲内の要素をランダムに埋めます。次に、各要素をそれぞれの要素で乗算しA
、B
積の合計を として識別される 3 番目の配列に格納しC
ます。A、B、C の配列のサイズを 100 に設定しました。
これにより、100 個のブロックと 128 個のスレッドを使用して並列化した 10,000 個の乗算が得られます (ワープ サイズのため)。
ここに私のカーネル関数があります:
__global__ void kernel(float *a, float *b, float *c, const int N) {
if( threadIdx.x < N )
c[blockIdx.x] += a[blockIdx.x] * b[threadIdx.x];
}
これは私の推論です。C
ピボット インデックスと同じインデックスを持つ集計を蓄積する必要があるため、正しく動作するはずの をA
再利用できます。blockidx.x
しかし、そうではありません。
私の疑いはC
、スレッドが変更されたときにインデックスがクリアされるか、共有されないということですが、アドバイスを求める理由が本当にわかりません。
これが完全なコードです。HANDLE_ERROR
短くするために関数ラッパーを明示的に避けました
#include <stdio.h>
#include <cuda.h>
#include <time.h>
#define M 100
__global__ void kernel(float *a, float *b, float *c, const int N) {
if(threadIdx.x < N)
c[blockIdx.x] += a[blockIdx.x] * b[threadIdx.x];
}
void init_array(float*, const int);
void fill_array(float*, const int, const float);
void print_array(float*, const int, *char);
int main (void) {
srand( time(NULL) );
float a[M], b[M], c[M] = { 0.0 };
float *dev_a, *dev_b, *dev_c;
const int S = sizeof(float) * M;
init_array(a, M);
init_array(b, M);
print_array(a, M, "a");
print_array(b, M, "b");
print_array(c, M, "c");
cudaMalloc((void**)&dev_a, S);
cudaMalloc((void**)&dev_b, S);
cudaMalloc((void**)&dev_c, S);
cudaMemcpy(dev_a, a, S, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, S, cudaMemcpyHostToDevice);
cudaMemcpy(dev_c, c, S, cudaMemcpyHostToDevice);
kernel<<<M, M + 28>>>(dev_a, dev_b, dev_c, M);
cudaMemcpy(c, dev_c, S, cudaMemcpyDeviceToHost);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
print_array(c, M, "c");
return 0;
}
void init_array(float *a, const int N) {
int i;
for(i=0; i<N; i++)
a[i] = rand() % M + 1;
}
void fill_array(float *a, const int N, const float v) {
int i;
for(i=0; i<N; i++)
a[i] = v;
}
void print_array(float *a, const int N, char *d) {
int i;
for(i=0; i<N; i++)
printf("\n%s[%d]: %f",d, i, a[i]);
}