这是我第二次尝试 CUDA 程序和并行开发。
我试图找出点积两个数组的原因。
例子:
给定
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
与每个 in相乘B
,并将乘积的总和存储在标识为 的第三个数组中C
。我已将数组 A、B 和 C 的大小设置为 100。
这给了我 10'000 次乘法,这些乘法是我使用 100 个块和 128 个线程(由于扭曲大小)并行化的。
这是我的内核函数:
__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]);
}