我最近写了一个简单的cuda程序,内核函数如下:
#define BLOCK_SIZE 16
#define RADIOUS 7
#define SM_SIZE BLOCK_SIZE+2*RADIOUS
__global__ static void DarkChannelPriorCUDA(const float* r, size_t ldr, const float* g, size_t ldg, const float* b, size_t ldb, float * d, size_t ldd, int n, int m)
{
__shared__ float R[SM_SIZE][SM_SIZE];
__shared__ float G[SM_SIZE][SM_SIZE];
__shared__ float B[SM_SIZE][SM_SIZE];
const int tidr = threadIdx.x;
const int tidc = threadIdx.y;
const int bidr = blockIdx.x * BLOCK_SIZE;
const int bidc = blockIdx.y * BLOCK_SIZE;
int i, j ,tr, tc;
for( i = 0; i < SM_SIZE; i += BLOCK_SIZE)
{
tr = bidr-RADIOUS+i+tidr;
for( j = 0; j < SM_SIZE; j += BLOCK_SIZE)
{
tc = bidc-RADIOUS+j+tidc;
if(tr <0 || tc<0 || tr>=n || tc>=m)
{
R[i][j]=1e20;
G[i][j]=1e20;
B[i][j]=1e20;
}
else
{
R[i][j]=r[tr*ldr+tc];
G[i][j]=g[tr*ldg+tc];
B[i][j]=b[tr*ldb+tc];
}
}
}
__syncthreads();
float results = 1e20;
for(i = tidr; i <= tidr + 2*RADIOUS; i++)
for(j = tidc; j <= tidc + 2*RADIOUS; j++)
{
results = results < R[i][j] ? results : R[i][j];
results = results < G[i][j] ? results : G[i][j];
results = results < B[i][j] ? results : B[i][j];
}
d[(tidr + bidr) * ldd + tidc + bidc] = results;
}
该函数读取r,g,b三个n * m的2d矩阵作为输入,输出n * m的矩阵d,d [i] [j]的每个元素的值等于其中的最小值r,g,b三个矩阵,由(2 * RADIOUS + 1)*(2 * RADIOUS + 1)窗口覆盖,中心(i,j)。
为了加快速度,我使用共享内存为每个块存储少量值。每个块有16 * 16个线程,每个单线程计算maxtrix d的一个元素的结果。共享内存需要存储(BLOCK_SIZE + 2 * RADIOUS)*(BLOCK_SIZE + 2 * RADIOUS)元素r,g,b。
但结果是错误的,共享内存R,G和B中的值与全局内存中的r,g和b不同。似乎全局内存中的数据永远不会成功分享共享内存,我无法理解它为什么会发生。
答案 0 :(得分:2)
你应该注意到每个线程执行的全局内部。当你写:
R[i][j]=r[tr*ldr+tc];
G[i][j]=g[tr*ldg+tc];
B[i][j]=b[tr*ldb+tc];
每个块中的不同线程都会覆盖在线程之间共享的R,G和B的[i] [j]分量。