一、核函数无故退出:
可能是由于传入的参数存储于主机内存中核函数访问不到,或者数组越界等原因。
例如:
1、传入了存储于主机的结构体,无论是结构体指针还是引用;
传入结构体引用时,调试的时候可能发现传入的结构体内容不正常,但是运算时却没有问题 。
2、传入了主机内存的指针。
可以在调试的时候进入反汇编发现该问题。
注意:
传入参数为基本类型时,不牵扯存储于主机的问题。
二、__syncthreads()以及其他核函数__cospif()无法找到或未定义
绝对是未调用正确的文件编译器,需要更改文件属性,使用项类型中的CUDA C++编译。
三、CUDA函数的结构
目前能够执行的包括两种:
1、头文件中包含调用核函数的函数,核函数定义在源文件中,例如:
//kern.h
#define NTHREADS 512
#define NBLOCKS 1024
__global__ void kernSum(int iLen, int *piSum, int *piA, int *piB);
__inline__ int devSum(int iLen, int *piSum, int *piA, int *piB)
{
kernSum<<<NBLOCKS, NTHREADS>>>(iLen, piSum, piA, piB);
}
//kern.cu
__global__ void kernSum(int iLen, int *piSum, int *piA, int *piB)
{
const int idx = blockDim.x*blockIdx.x + threadIdx.x;
if (idx < iLen)
{
piSum[i] = piA[i] + piB[i];
}
}
优点:函数内联,编译时直接展开
缺点:头文件中定义的变量可能会被多次定义
2、头文件声明函数,源文件定义核函数以及相应的其他函数,例如:
//kern.h
int devSum(int iLen, int *piSum, int *piA, int *piB)
//kern.cu
#define NTHREADS 512
#define NBLOCKS 1024
__global__ void kernSum(int iLen, int *piSum, int *piA, int *piB)
{
const int idx = blockDim.x*blockIdx.x + threadIdx.x;
if (idx < iLen)
{
piSum[i] = piA[i] + piB[i];
}
}
int devSum(int iLen, int *piSum, int *piA, int *piB)
{
kernSum<<<NBLOCKS, NTHREADS>>>(iLen, piSum, piA, piB);
}
优点:头文件干净整洁
缺点:每次都是调用,可能影响效率
四、工程需要调用cuda核函数
1、工程属性里更改为cuda编译器;
2、将核函数存在的文件以及调用核函数的文件属性改为Cuda C++。注意:内联展开的情况下,核函数可能展开到的所有文件属性都需要更改。也就是包含头文件的所有源文件都要使用 cuda C++属性。
五 vs编译时,如果无法识别出核函数调用(也就是三对尖括号)。
一定是该源文件使用了C/C++编译器,而非NVCC,在该源文件的属性中将编译器改为CUDA C++ 即可。
使用cudaMallocManaged()函数分配内存时,如果核函数调用之后不使用cudaDeviceSynchronize()同步直接访问内存可能产生异常,报“代码地址访问该内存地址失败”
cuda核计算数据时,按顺序计算,并不提前统一所有数据类型;
例如:x=2*3/5*0.25;x结果是0.25,而不是0.3;