我正在使用CUDA做我的第一步,并尝试实现简单的直方图计算。我只是将数组拆分为多个块和线程,并可以选择让一个线程计算while
循环的两次迭代。
这是我的CUDA内核,首先我想了解的是,atomicAdd访问与不安全写入直方图数组相比要慢得多。但是,当我检查nvprof
的输出时,输出显示了1073741824个元素(1<<30
)和BlockSize
的128个数组以及GridSize
的8388608的数组,该输出:>
13.49% 126.33ms 1 126.33ms 126.33ms 126.33ms histogram_unsafe(int*, int*)
12.01% 112.49ms 1 112.49ms 112.49ms 112.49ms histogram_safe(int*, int*)
(通过这种配置,每个线程都会执行一次循环迭代)
但是在我的幻想中,不安全的代码应该更快吗?至少,不安全代码不会产生正确的结果,而安全代码会产生正确的结果。但是我不明白为什么不安全的版本要慢一些?是否有一些我不知道的关于CUDA大气的东西的经验法则?
这是我的内核代码:
__global__ void histogram_[unsafe/save]( int *input, int *hist ) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
while (tid < N) {
int bin = input[tid] & MASK;
// Of course I use only one version at a time
hist[bin]++; // unsafe
atomicAdd(&hist[bin], 1); // safe
tid += blockDim.x * gridDim.x;
}
}