我有一张CUDA卡:Cuda Compute功能(3.5)如果我有一个名为<<<<<<<<<<<<< ,内核中发生的迭代次数是多少?我以为是(2000 * 512),但测试没有证明这一点?我还要确认我计算变量的方式是正确的。
情况是,在内核中,我根据线程号递增传递的全局内存号:
int thr = blockDim.x * blockIdx.x + threadIdx.x;
worknumber = globalnumber + thr;
所以,当我回到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);
}
}
答案 0 :(得分:2)
如果您启动配置为<<<X,Y>>>
的内核,并且您没有违反任何CUDA使用规则,那么启动的线程数实际上将是X * Y(或者对其进行适当的修改)如果我们正在谈论2维或3维线程块和/或网格,即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
$
请注意,原子操作可能相对较慢。出于性能原因,我不建议定期使用此类代码。但是如果你想说服自己发布的线程数量,它应该给出正确的答案。