2012-07-29 81 views
0

我在GPU上运行一些图像处理操作,我需要输出的直方图。 我已经编写并测试了处理内核。此外,我还分别测试了输出图片样本的直方图内核。他们都能很好地工作,但是当我把他们全部放在一个循环中时,我什么也得不到。原子操作中断所有内核

这是我的直方图内核:

__global__ void histogram(int n, uchar* color, uchar* mask, int* bucket, int ch, int W, int bin) 
{ 
    unsigned int X = blockIdx.x*blockDim.x+threadIdx.x; 
    unsigned int Y = blockIdx.y*blockDim.y+threadIdx.y; 

    int l = (256%bin==0)?256/bin: 256/bin+1; 
    int c; 

    if (X+Y*W < n && mask[X+Y*W]) 
    { 
     c = color[(X+Y*W)*3]/bin; 
     atomicAdd(&bucket[c], 1); 

     c = color[(X+Y*W)*3+1]/bin; 
     atomicAdd(&bucket[c+l], 1); 

     c = color[(X+Y*W)*3+2]/bin; 
     atomicAdd(&bucket[c+l*2], 1); 
    } 
} 

它正在更新直方图矢量红,绿,蓝(“L”是向量的长度) 当我注释掉atomicAdds再次产生。输出但当然不是直方图。 他们为什么不一起工作?

编辑:

这是循环:

cudaMemcpy(frame_in_gpu,frame_in.data, W*H*3*sizeof(uchar),cudaMemcpyHostToDevice); 
    cuda_process(frame_in_gpu, frame_out_gpu, W, H, dimGrid,dimBlock); 
    cuda_histogram(W*H, frame_in_gpu, mask_gpu, hist, 3, W, bin, dimg_histogram, dimb_histogram); 

然后我复制输出到主机内存,并将其写入到视频。 这些是仅通过dimGrid和dimBlock作为输入调用其内核的c代码。另外:

dim3 dimBlock(32,32); 
dim3 dimGrid(W/32,H/32); 
dim3 dimb_Histogram(16,16); 
dim3 dimg_Histogram(W/16,H/16); 

我改变了这个直方图,因为它的效果更好。有关系吗?

编辑2: 我正在使用-arch = sm_11选项进行编译。我只是在某处读过它。有谁能告诉我该如何选择它?

+0

你能提供使用它的代码吗? – geek 2012-07-29 08:36:20

+0

这是在Windows Vista或Windows 7上?在Linux上是 – talonmies 2012-07-29 13:53:48

+0

。 Ubuntu 11.10。另外我的GPU是gtx550 – 2012-07-29 14:27:18

回答

1

也许你应该尝试编译没有-arch = sm_11标志。 sm 1.1是第一种支持全局内存原子操作的架构,而您的GPU支持SM 2.0。因此,除了向后兼容性外,没有理由为SM 1.1进行编译。

一个可能的问题可能是SM 1.1不支持全局内存中的64位整数的原子操作。所以我建议你在不使用-arch选项的情况下重新编译代码,或者使用 -arch = sm_20如果你喜欢