我无法理解简单 Cuda 内核中的错误。我将内核缩小到仍然显示错误的最小值。
我有一个“多边形”类,它只存储一些点。我有一个“添加一个点”的函数(只是增加计数器),我向我的多边形数组中的所有多边形添加 4 个点。最后,我调用一个使用循环更新点数的函数。如果在这个循环中我调用new_nbpts++
一次,我会得到预期的答案:所有多边形都有 4 个点。如果在同一个循环中我new_nbpts++
第二次调用,那么我的多边形有一个垃圾点数(4194304 个点),这是不正确的(我应该得到 8 个)。
我希望有一些我误解的东西。
完整的内核:
#include <stdio.h>
#include <cuda.h>
class Polygon {
public:
__device__ Polygon():nbpts(0){};
__device__ void addPt() {
nbpts++;
};
__device__ void update() {
int new_nbpts = 0;
for (int i=0; i<nbpts; i++) {
new_nbpts++;
new_nbpts++; // calling that a second time screws up my result
}
nbpts = new_nbpts;
}
int nbpts;
};
__global__ void cut_poly(Polygon* polygons, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx>=N) return;
Polygon pol;
pol.addPt();
pol.addPt();
pol.addPt();
pol.addPt();
for (int i=0; i<N; i++) {
pol.update();
}
polygons[idx] = pol;
}
int main(int argc, unsigned char* argv[])
{
const int N = 20;
Polygon p_h[N], *p_d;
cudaError_t err = cudaMalloc((void **) &p_d, N * sizeof(Polygon));
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
cut_poly <<< n_blocks, block_size >>> (p_d, N);
cudaMemcpy(p_h, p_d, sizeof(Polygon)*N, cudaMemcpyDeviceToHost);
for (int i=0; i<N; i++)
printf("%d\n", p_h[i].nbpts);
cudaFree(p_d);
return 0;
}