我如何计算正在启动的 CUDA 线程数?

How do i calculate the number of CUDA threads being launched?

我有一张 CUDA 卡:Cuda 计算能力 (3.5) 如果我有一个调用,如 <<<2000,512>>>,内核中发生的迭代次数是多少?我以为是(2000*512),但测试不能证明这一点?我还想确认我计算变量的方式是否正确。

情况是,在内核中我根据线程号递增传递的全局内存号:

  int thr = blockDim.x * blockIdx.x + threadIdx.x;
  worknumber = globalnumber + thr;

所以,当我 return 回到 CPU 时,我想知道到底有多少增量,这样我就可以保持跟踪,这样我就不会在回忆时重复或跳过数字内核 GPU 来处理我的下一组数字。

编辑:

__global__ void allin(uint64_t *lkey, const unsigned char *d_patfile)
{

    uint64_t kkey;
    int tmp;
    int thr = blockDim.x * blockIdx.x + threadIdx.x;
    kkey = *lkey + thr;

if (thr > tmp) {
    tmp = thr;
    printf("%u \n", thr);
    }
}

如果您使用 <<<X,Y>>> 配置启动内核,并且您没有违反任何 CUDA 使用规则,那么启动的线程数实际上将是 X*Y(或适当的修改如果我们谈论的是 2 维或 3 维线程块 and/or 网格,即 X.x*X.y*X.z*Y.x*Y.y*Y.z )。

来自 CUDA 内核的

printf 有多种 limitations。因此,从 CUDA 内核生成大量 printf 输出通常是不明智的,并且可能对验证在大型网格中启动的线程数没有用。

如果您想跟踪实际启动的线程数,您可以使用全局变量并让每个线程自动更新它。像这样:

$ cat t848.cu
#include <stdio.h>

__device__ unsigned long long totThr = 0;

__global__ void mykernel(){

  atomicAdd(&totThr, 1);
}

int main(){

  mykernel<<<2000,512>>>();
  unsigned long long total;
  cudaMemcpyFromSymbol(&total, totThr, sizeof(unsigned long long));
  printf("Total threads counted: %lu\n", total);
}
$ nvcc -o t848 t848.cu
$ cuda-memcheck ./t848
========= CUDA-MEMCHECK
Total threads counted: 1024000
========= ERROR SUMMARY: 0 errors
$

请注意,原子操作可能相对较慢。出于性能原因,我不建议定期使用此类代码。但是如果你想说服自己启动的线程数,它应该给出正确的答案。