CUDA内核和printf的奇怪行为

CUDA kernel and printf strange behaviour.

本文关键字:内核 printf CUDA      更新时间:2023-10-16

我写了简单的内核代码,试图操作一维数组元素:

    #include "stdio.h"
__global__ void Loop(double *X, int CellsNum, int VarNum,const double constant1)
{
int idx = threadIdx.x+blockDim.x*blockIdx.x;
int i = (idx+1)*VarNum ;
double exp1,exp2,exp3,exp4 ;
if(idx<CellsNum-2) {
exp1=double(0.5)*(X[i+6+VarNum]+X[i+6])+X[i+10] ;
exp2=double(0.5)*(X[i+8+VarNum]+X[i+8]) ;
if(i==0) {
printf("%e %e",exp1,exp2) ;
}
exp3=X[i+11]-constant1*(exp1*exp2)/X[i+5] ;
exp4=constant1*(X[i+9]*exp1-X[i+9-VarNum]*exp2)/X[i+5] ;
X[i+12]=exp3+exp4;
}
}
extern "C" void cudacalc_(double *a, int* N1, int* N2, double* N3)
{
int Cells_Num = *N1;
int Var_Num = *N2;
double constant1 = *N3;
Loop<<<1,Cells_Num>>>(a,Cells_Num,Var_Num,constant1);
}

但如果我评论这段代码,它就不起作用了:

if(i==0) {
printf("%e %e",exp1,exp2) ;
}

即使变量i总是大于零。然后我评论这行代码在X数组中生成NaN。我正试图在特斯拉GPU上运行这段用-arch sm_20标志编译的代码。也许有人能帮我解决这个问题?

这个内核有机会出现竞争条件,因为内核代码在没有同步或保护的情况下从X读取和写入X

解决此问题的最简单方法可能是将输出语句分离以写入不同的数组:

Xo[i+12]=exp3+exp4;

cuda-memcheck可以帮助检查内核中的竞争条件。使用cuda-memcheck --help查找特定的racecheck选项。