Cuda 内核启动失败

Cuda 内核启动失败,cuda,runtime-error,reduce,Cuda,Runtime Error,Reduce,我在Linux系统和特斯拉C2075机器上操作。我正在启动一个内核,它是reduce内核的一个修改版本。我的目标是找到一个大数据集(结果)的平均值和一个逐步平均的版本(时间平均值)。请参阅下面的代码 “结果”和“时间平均值”的大小与“NSAMP”相同。“time_avg”包含阵列结果的连续平均集。所以,上半部分包含每两个不重叠样本的平均值,下一季度包含每四个不重叠样本的平均值,下八分之一包含8个样本的平均值,依此类推 __global__ void timeavg_mean(float *res

我在Linux系统和特斯拉C2075机器上操作。我正在启动一个内核,它是reduce内核的一个修改版本。我的目标是找到一个大数据集(结果)的平均值和一个逐步平均的版本(时间平均值)。请参阅下面的代码

“结果”和“时间平均值”的大小与“NSAMP”相同。“time_avg”包含阵列结果的连续平均集。所以,上半部分包含每两个不重叠样本的平均值,下一季度包含每四个不重叠样本的平均值,下八分之一包含8个样本的平均值,依此类推

__global__ void timeavg_mean(float *result, unsigned int *nsamps, float *time_avg, float *mean) {

__shared__ float temp[1024];
int ltid = threadIdx.x, gtid = blockIdx.x*blockDim.x + threadIdx.x, stride;
int start = 0, index;
unsigned int npts = *nsamps;

printf("here here\n");

// Store chunk of memory=2*blockDim.x (which is to be reduced) into shared memory
if ( (2*gtid) < npts ){
        temp[2*ltid] = result[2*gtid];
        temp[2*ltid+1] = result[2*gtid + 1]; 
}    
        for (stride=1; stride<blockDim.x; stride>>=1) {
                __syncthreads();
                if (ltid % (stride*2) == 0){ 
                  if ( (2*gtid) < npts ){
                        temp[2*ltid] += temp[2*ltid + stride];
                        index = (int)(start + gtid/stride);
                        time_avg[index] = (float)( temp[2*ltid]/(2.0*stride) );
                  }   
                }   
        start += npts/(2*stride);
        }   
__syncthreads();
if (ltid == 0)
{
        atomicAdd(mean, temp[0]);    
}
__syncthreads();
printf("%f\n", *mean);
}
\uuuuu全局\uuuu无效时间平均值(浮点*结果,无符号整数*nsamps,浮点*时间平均值,浮点*平均值){
__共享浮点数温度[1024];
int ltid=threadIdx.x,gtid=blockIdx.x*blockDim.x+threadIdx.x,步长;
int start=0,索引;
无符号整数npts=*nsamps;
printf(“此处\n”);
//将内存块=2*blockDim.x(要减少)存储到共享内存中
如果((2*gtid)=1){
__同步线程();
如果(ltid%(步幅*2)==0{
如果((2*gtid)
启动配置为40个块,512个线程。数据集约为40k个样本

在我的主代码中,我在内核调用之后调用
cudaGetLastError()
,它不会返回任何错误。内存分配和内存拷贝不返回错误。如果我在内核调用后写入
cudaDeviceSynchronize()
(或使用
cudaMemcpy
检查平均值),则程序在内核调用后完全挂起。若我删除它,程序运行并退出。在这两种情况下,我都不会得到输出“此处-此处”或打印的平均值。我理解,除非内核成功执行,否则printf不会打印。 这与递归中的
\uu syncthreads()
有关吗?所有的线都会一直延伸到相同的深度,所以我认为这是正确的

这里有什么问题


谢谢大家!

内核调用是异步的,如果内核成功启动,您的主机代码将继续运行,并且不会看到任何错误。内核运行期间发生的错误只有在执行显式同步或调用导致隐式同步的函数后才会出现。
如果您的主机挂起了同步,而您的内核可能没有完成运行—它可能正在运行某个无限循环,或者正在等待某个
\uu synchthreads()
或其他一些同步原语。

您的代码似乎包含一个无限循环:
for(stride=1;stride>=1)
。您可能希望向左而不是向右移动步幅:
stride内核调用是异步的,如果内核成功启动,您的主机代码将继续运行,并且您不会看到任何错误。内核运行期间发生的错误只有在执行显式同步或调用导致隐式同步的函数后才会出现。
如果您的主机挂起了同步,而您的内核可能没有完成运行—它可能正在运行某个无限循环,或者正在等待某个
\uu synchthreads()
或其他一些同步原语。

您的代码似乎包含一个无限循环:
for(stride=1;stride>=1)
。您可能希望向左而不是向右移动步幅:
stride您的内核有一个无限循环。将for循环替换为

for (stride=1; stride<blockDim.x; stride<<=1) {

for(stride=1;stride您的内核有一个无限循环。将for循环替换为

for (stride=1; stride<blockDim.x; stride<<=1) {

for(stride=1;stride=1)好吧,我没意识到这是一个无限循环。谢谢!操作符“>>=”和“按位移位运算符将位向左或向右移位。因为更重要的位位于左侧,所以向左移位意味着将值乘以2,向右移位意味着除以2。您可以使用cuda调试器调试内核,您可以在内核内设置断点并执行常规调试工作(步进/步出/结束、检查变量等)。递归调用是函数(直接或间接)调用自身的调用。您所描述的是循环内的正常函数调用。对,我忘记了。谢谢!代码现在正在运行并终止,但我得到的平均值是错误的。知道为什么吗?我只是在这里添加值,所以我在除以样本数后检查平均值。它不是错误的数量级,而是小于约20%好吧,我没意识到这是一个无限循环。谢谢!操作符“>>=”和“按位移位运算符将位向左或向右移位。因为更重要的位位于左侧,所以向左移位意味着将值乘以2,向右移位意味着除以2。您可以使用cuda调试器调试内核,您可以在内核内设置断点并执行常规调试工作(步进/步出/结束、检查变量等)。递归调用是函数(直接或间接)调用自身的调用。您所描述的是循环内的正常函数调用。对,我忘记了。谢谢!代码现在正在运行并终止,但我得到的平均值是错误的。知道为什么吗?我只是在这里添加值,所以我在除以样本数后检查平均值。它不是错误的数量级,而是小于约20%比预期的要多。