非常感谢版主的耐心,第一次发帖很多地方不懂还望见谅。昨天仔细想了一下修改了下程序,把我原本在kernel中生成的高斯模板放到CPU中去完成,改进后只把完成好的55高斯模板放到GPU中去即可,确是一开始没考虑到这个问题只是简单地把CPU中的程序丢到kernel中。这样处理后,问题基本上解决了,我想问题可能是在线程同步的情况下,每个线程都会去执行高斯模板的生成步骤,会导致高斯模板生成的时候出现一些错误,因为高斯模板的数组存贮在Global Memory中(不知道这样解释是否正确)。每个线程在执行的时候都回去访问这个数组。修改后的代码:
global static void GpuCalculate(double pdKernal_2,unsigned char *pCanny,unsigned char data,clock_t time,int m,int n)
{
int i,j; //循环变量
int lineByte=(m8/8+3)/44;
int nWidowSize=5;
int nCenter = nWidowSize/2; //定义滤波窗口中心的索引
int nWidth = m; //获取图像的像素宽度
int nHeight =n; //获取图像的像素高度
//GPU中无法定义数组,数组需要的空间需要全部从CPU中开始定义分配。
int tid = threadIdx.x;
int size =nHeight/ THREAD_NUM;
int bid = blockIdx.x;
clock_t start;
if(tid == 0)
{
start=clock();
}
int x;
int y;
for(i=tid*size;i<(tid+1)size; i++)
{
for(j=0; j<nWidth; j++)
{
double dFilter=0.0;
double dSum = 0.0;
for(x=(-nCenter); x<=nCenter; x++) //行
{
for(y=(-nCenter); y<=nCenter; y++) //列
{
if( (j+x)>=0 && (j+x)<nWidth && (i+y)>=0 && (i+y)<nHeight) //判断边缘
{
dFilter += (double)data[(i+y)nWidth + (j+x)] * pdKernal_2[(y+nCenter)nWidowSize+(x+nCenter)];
dSum += pdKernal_2[(y+nCenter)nWidowSize+(x+nCenter)];
}
}
}
pCanny[i*nWidth+j] = (unsigned char)dFilter/dSum;
}
}
if(tid==0)
{
time=clock()-start;
}
}
主函数中:
cudaMalloc((void) &time, sizeof(clock_t));
//在显卡内部开辟一个显示时间的内存
cudaMalloc((void) &gpudata, sizeof(unsigned char)xy);
cudaMalloc((void*) &pdKernal, sizeof(double)55);
cudaMalloc((void**) &GpuTempdata,sizeof(unsigned char)xy);
//开辟内存存放数组
cudaMemcpy(gpudata, pBmpbuf, sizeof(unsigned char)xy,cudaMemcpyHostToDevice);
cudaMemcpy(pdKernal, pdKernal_2, sizeof(double)55,cudaMemcpyHostToDevice);
//将CPU中的的数组复制到显卡内存中
GpuCalculate<<<BLOCK_NUM,THREAD_NUM,0>>>(pdKernal,GpuTempdata,gpudata,time,x,y);
//在Gpu中进行计算
clock_t time_used;
//在Cpu中定义Gpu计算的时间变量
cudaMemcpy(GetResult, GpuTempdata, sizeof(unsigned char)xy,cudaMemcpyDeviceToHost);
//取出GPU中计算的数据
cudaMemcpy(&time_used,time,sizeof(clock_t),cudaMemcpyDeviceToHost);
//从Gpu显卡中取出时间
saveBmp(GpuwritePath,GetResult,bmpWidth, bmpheight,8,bmpColorTable);