我有一个循环,我试图在 CUDA 中并行化。它是这样的:
float *buf = new float[buf_size]; // buf_size <= 100
for (int j; j<N; j++){
caluculate_with(buf);
}
delete [] buf;
循环的本质是每次迭代开始时缓冲区数组中的值都没有关系。这样循环本身就可以非常简单地并行化。
但是在 CUDA 中,由于对内核的异步调用,我现在需要一个更大的缓冲区。
void __global__ loop_kernel(float *buf_gpu) {
const int idx = index_gpu(blockIdx, blockDim, threadIdx);
float *buf = buf_gpu + (idx*buf_size);
caluculate_with(buf);
}
....
float * buf_gpu;
cudaMalloc(&buf_gpu,sizeof(float)*N*buf_size);
loop_kernel<<<mesh,block>>>(buf_gpu);
cudaFree(buf_gpu);
}
由于对内核的每次调用都会获得自己的缓冲区段,因此缓冲区大小现在随着循环大小 N 缩放,这显然是有问题的。我现在必须分配(缓冲区大小 * 循环大小),而不是使用(缓冲区大小)内存量。在我正在处理的问题中,我的 GTX590 的 GPU 内存限制达到了某种典型的 N 值)。
编辑:详细说明我的其他尝试。由于 buf_size 不是太大,我也尝试过这样重写内核:
void __global__ loop_kernel() {
float *buf = new float[buf_size];
caluculate_with(buf);
delete [] buf;
}
...
assert(cudaSuccess == cudaDeviceSetLimit(cudaLimitMallocHeapSize,8*1024*1024));
loop_kernel<<<mesh,block>>>();
assert(cudaSuccess == cudaDeviceSynchronize());
cudaDeviceSynchronize() 断言失败,返回状态为 4。不知道这意味着什么。