刚刚学cuda的时候以为调用核函数的时候可以开辟任意大小的线程,所以当自己尝试用cuda实现卷积运算的时候,调用核函数的时候用了这样的写法cudaConv<<<1,memSize>>>(gpuMem);
实际上cuda每个block的线程数是有上限的。
下面这个知乎答案说明了怎样获取cuda可开辟的最大线程数。
https://www.zhihu.com/question/462801801/answer/1925184931
当需要开辟多于maxThreadsPerBlock个线程的时候,需要在调用核函数的时候配合block使用。
下面是一个具体的调用例子,实现对一个数组的每一位数字实现+1操作。
#include<iostream>
//传入的第2个参数表示数据的个数
__global__ void bigMatAdd(int* gpuMem,unsigned int dataSize)
{
//当前位置的线程标号
int thrId=threadIdx.x;
//当前位置的线程块标号
int blkId=blockIdx.x;
//当前线程需要操作的位置
int dstLocal=blkId*blockDim.x+thrId;
//判断线程操作位置是否超过了范围
if(dstLocal<dataSize)
{
//对目标内存做操作
gpuMem[dstLocal]+=1;
}
}
int main()
{
//数据的大小
const unsigned int dataSize=4000*1000;
const unsigned int threadSize=1000;
//新建相应大小的cpu数据
unsigned char cpuData[dataSize];
//对所有的cpu数据依次赋值
for(int i=0;i<dataSize;++i) cpuData[i]=10;
//定义gpu数据
int* gpuData;
//开辟gpu数据的空间
cudaMalloc((void**)&gpuData,sizeof(int)*dataSize);
//把cpu数据复制到gpu里面
cudaMemcpy(gpuData,cpuData,sizeof(int)*dataSize,cudaMemcpyHostToDevice);
//调用核函数
bigMatAdd<<<dataSize/threadSize+1,threadSize>>>(gpuData,dataSize);
//把gpu里面的数据复制到cpu里面
cudaMemcpy(cpuData,gpuData,sizeof(int)*dataSize,cudaMemcpyDeviceToHost);
//遍历复制后的cpu数据,检测它们的数据是否都正常
for(int i=0;i<dataSize;++i)
{
if(cpuData[i]!=11)
{
std::cout<<cpuData[i]<<std::endl;
break;
}
}
return 0;
}