在CUDA中使用全局内存初始化共享内存时出错

时间:2014-04-28 13:21:10

标签: c memory cuda gpu gpu-programming

我最近写了一个简单的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不同。似乎全局内存中的数据永远不会成功分享共享内存,我无法理解它为什么会发生。

1 个答案:

答案 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]分量。