我正在尝试使用共享内存在GPU上使用过滤器3x3对数据阵列256x256进行卷积。我知道我要在块中打破阵列,然后在每个块中应用过滤器。这最终意味着沿边缘重叠的块,并且需要在没有数据的边缘周围进行一些填充,以便过滤器正常工作。
int grid = (256/(16+3-1))*(256/(16+3-1))
其中256是我的数组的长度或宽度,16是我的块在共享内存中的长度或宽度,3是我的过滤器的长度或宽度,我减去一个使它成为偶数。
int thread = (16+3-1)*(16+3-1)
现在我调用我的内核<<>>(输出,输入,256) 输入和输出是一个大小为256 * 256
的数组__global__ void kernel(float *input, float *output, int size)
{
__shared__ float tile[16+3-1][16+3-1];
blockIdx.x = bIdx;
blockIdy.y = bIdy;
threadIdx.x = tIdx;
threadIdy.y = tIdy
//i is for input
unsigned int iX = bIdx * 3 + tIdx;
unsigned int iY = bIdy * 3 + tIdy;
if (tIdx == 0 || tIdx == width || tIdy == 0 || tIdy == height)
{
//this will pad the outside edges
block[tIdy][tIdx] = 0;
}
else
{
//This will fill in the block with real data
unsigned int iin = iY * size + iX;
block[tIdy][tIdx] = idata[iin];
}
__syncthreads();
//I believe is above is correct; below, where I do the convolution, I feel is wrong
float result = 0;
for(int fX=-N/2; fX<=N/2; fX++){
for(int fY=-N/2; fY<=N/2; fY++){
if(iY+fX>=0 && iY+fX<size && iX+fY>=0 && iX+fY<size)
result+=tile[tIdx+fX][tIdy+fY];
}
}
output[iY*size+iX] = result/(3*3);
}
当我运行代码时,如果我运行卷积部分,我会收到内核错误。任何见解?还是建议?
答案 0 :(得分:3)
查看sobelFilter SDK示例。
它使用纹理来处理边缘情况,稍微过度获取块(但纹理缓存使效率更高),并使用共享内存进行处理。
共享内存的一个微妙之处在于,如果读取相邻字节,则会出现4路存储区冲突。在sobelFilter示例中说明的解决此问题的一种方法是展开循环4x并访问每第四个字节。