有1个char型的数组,长度为nBytes(很大),要求分别找出每1024个点fft之后的幅度最大值及序号。
我采用的步骤是: kernel1(浮点转换)–>cufft–>kernel2(搜索最大值)
kernel1的作用是浮点转换,char型数据不能直接cufft,大概nBytes/1024个block,每个block有1024个线程
cufft每次2048点,大概分nBytes/2048次,cufft每次输出1025点,前1024点有效
kernel2的作用是搜索,大概nBytes/1024个block,每个block有1024个线程
我这里说的block的次数都是大概是为了说明简单,具体见程序里面
出现的问题是,在kernel2返回后进行cudaMemcpy的时候操作系统就没有反应了(刚开始鼠标能动,后来鼠标也不能动了),kernel2后面加的cudaGetLastError返回的是no error。。。
比较急,请版主帮忙解答下,谢谢
不晓得源码贴上去怎么好看,望见谅
先贴2个kernel的代码
//数据格式转换,
global static void DataFormatChange(unsigned char *pBufChar,float pBufFloat,int nByte)
{
const int threadID= threadIdx.x;
const int blockID= blockIdx.x;
int IndexThread=blockIDblockDim.x+threadID;
if(IndexThread<nByte)
(pBufFloat+IndexThread)=(float)((BYTE)((pBufChar+IndexThread)));
}
//搜索频谱幅度最大值
global static void GetMaxAmpIndexAndFilter(cufftComplex *pFFTSource,cufftComplex pLvboResult,float MaxResult)
{
const int threadID= threadIdx.x;
const int blockID= blockIdx.x;
int IndexThread=blockIDblockDim.x+threadID;
int IndexData=blockID(NPoint/2+1)+threadID;//cufft之后每段数据长度是1025,实际只需要用到1024
extern shared float ABSResult;
extern shared int IndexTmp;
cufftComplex valueTmp=(pFFTSource+IndexData);
ABSResult[threadID]=valueTmp.xvalueTmp.x+valueTmp.y*valueTmp.y;
__syncthreads();
//求模之后查找最大值序号
IndexTmp[threadID]=threadID;
int offset=blockDim.x>>1;
while(offset>0)
{
if(threadID<offset)
{
if(ABSResult[threadID]<ABSResult[threadID+offset])
{
ABSResult[threadID]=ABSResult[threadID+offset];
IndexTmp[threadID]=IndexTmp[threadID+offset];
}
offset >>= 1;
}
__syncthreads();
}
__syncthreads();
if(threadID==0)
*(MaxResult+blockID)=ABSResult[0];
//幅度最大值序号
shared int IndexMax;
IndexMax=IndexTmp[0];
if(threadID<IndexMax+10&&threadID>IndexMax-10)
*(pLvboResult+IndexThread)=valueTmp;
}
主要代码部分是
//原始采样数据
unsigned char pSource_D;
cudaMallocHost((void*)&pSource_D,sizeof(unsigned char)*nBytes);
cudaMemcpy(pSource_D,pbuf,sizeof(unsigned char)*nBytes,cudaMemcpyHostToDevice);
UINT ThreadSize=1024;
UINT BlockSize=(nBytes+ThreadSize-1)/ThreadSize;
UINT SizeData=ThreadSize*BlockSize; //浮点转换数据长度
//存储浮点转换后的数据
float pFilebuf,pFilebuf_D;
cudaHostAlloc((void)&pFilebuf, sizeof(float)*SizeData,cudaHostAllocMapped);
cudaMemset(pFilebuf,0,sizeof(float)*SizeData);
cudaHostGetDevicePointer((void **)&pFilebuf_D,(void *)pFilebuf,0);
//采样数据浮点转换
DataFormatChange<<<BlockSize,ThreadSize>>>(pSource_D,pFilebuf_D,nBytes);
cudaFreeHost((void*)pSource_D);
UINT BlockFFTSize=(SizeData+NPoint-1)/NPoint;
UINT SizeFFTData=(NPoint/2+1)*BlockFFTSize; //CUFFT计算长度为N/2+1
//CUFFT
cufftComplex pFFTout,pFFTout_D;
cudaHostAlloc((void)&pFFTout, sizeof(cufftComplex)*SizeFFTData,cudaHostAllocMapped);
cudaHostGetDevicePointer((void *)&pFFTout_D,(void )pFFTout,0);
cufftHandle plan;
cufftPlan1d(&plan,NPoint,CUFFT_R2C,BlockFFTSize);
cufftExecR2C(plan,(cufftReal)(pFilebuf_D),(cufftComplex)pFFTout_D);
cudaMemcpy(pFFTout,pFFTout_D,sizeof(cufftComplex)SizeFFTData,cudaMemcpyDeviceToHost);
cudaFreeHost((void)pFilebuf);
cufftDestroy(plan);
//保存单个block块中的最大值
float absMax,absMax_D;
cudaHostAlloc((void)&absMax,sizeof(float)*BlockFFTSize,cudaHostAllocMapped);
cudaHostGetDevicePointer((void **)&absMax_D,(void *)absMax,0);
//保存最后输出
UINT SizeLvboData=NPoint/2*BlockFFTSize;
cufftComplex pFFTLvbo,pFFTLvbo_D;
cudaHostAlloc((void)&pFFTLvbo,sizeof(cufftComplex)*SizeLvboData,cudaHostAllocMapped);
cudaMemset(pFFTLvbo,0,sizeof(cufftComplex)*SizeLvboData);
cudaHostGetDevicePointer((void **)&pFFTLvbo_D,(void *)pFFTLvbo,0);
//搜索频谱中幅度最大点
GetMaxAmpIndexAndFilter<<<BlockFFTSize,ThreadSize,ThreadSize*(sizeof(float)+sizeof(int))+sizeof(int)>>>(pFFTout_D,pFFTLvbo_D,absMax_D);
const char* error;
error=cudaGetErrorString(cudaGetLastError());
cudaMemcpy(absMax,absMax_D,sizeof(float)*BlockFFTSize,cudaMemcpyDeviceToHost);
cudaMemcpy(pFFTLvbo,pFFTLvbo_D,sizeof(cufftComplex)*SizeLvboData,cudaMemcpyDeviceToHost);