我如何计算正在启动的 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
$
请注意,原子操作可能相对较慢。出于性能原因,我不建议定期使用此类代码。但是如果你想说服自己启动的线程数,它应该给出正确的答案。
我有一张 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
)。
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
$
请注意,原子操作可能相对较慢。出于性能原因,我不建议定期使用此类代码。但是如果你想说服自己启动的线程数,它应该给出正确的答案。