CUDA是不是很好地优化了这段代码,还是我错了?

时间:2014-03-04 11:23:55

标签: c++ optimization cuda

以下是我正在处理的一段代码,并且已经收到了我没想到的结果。我已经删除了我的完整代码块以突出显示问题。我希望在此块的末尾spID应该是一个tid值的块,但lbBooltrue的{​​{1}}除外spID_CCL_SHARED_MEM_MAX_VALUE (255)。但是,如果我使用NSight调试__syncthreads()处的数据,我会发现所有spID值等于lbBool true为{0}。

我的块由16乘16个线程组成,因此uint8足以存储所有值(0-255)。我意识到将会有一个ID为255的有效像素和一个值为255的死像素。这很好。

我正在unsigned long使用tOut

在这种情况下,我的图像是100x100但是我尝试过的每个图像尺寸都失败了。 我正在运行GTX 580并经常使用256线程的内核。

调用内核:

#define _CCL_SHARED_MEM_TYPE uint8
#define _CCL_SHARED_MEM_MAX_VALUE 255

template<class tOut> tOut *nsGPUBaseClasses::IbxCCL4Link(bool *lbEdges,uint32 liImageWidth,uint32 liImageHeight,tOut *lpOut)
{
dim3 liThreads(16,16);
dim3 liBlocks((liImageWidth+liThreads.x-1)/liThreads.x,(liImageHeight+liThreads.y-1)/liThreads.y);

if(lpOut == nullptr) _CHECK_CUDA_ERROR(cudaMalloc(&lpOut,sizeof(tOut)*liImageWidth*liImageHeight));

IbxCCL4LinkCUDA<<<liBlocks,liThreads,(sizeof(_CCL_SHARED_MEM_TYPE)*liThreads.x*liThreads.y+sizeof(bool)*2)>>>(lbEdges,liImageWidth,liImageHeight,lpOut);

_CHECK_CUDA_ERROR_EMPTY();

return lpOut;
}

核心本身:

template<class tOut> void __global__ IbxCCL4LinkCUDA(bool *lbBool,unsigned long liImageWidth,unsigned long liImageHeight,tOut *lpOut)
{
    // Shared Memory
    __shared__ float lbSpecific[];
    _CCL_SHARED_MEM_TYPE *spID=reinterpret_cast<_CCL_SHARED_MEM_TYPE*>(&lbSpecific);

    //IDs for thread
    unsigned long tid = threadIdx.x+threadIdx.y*blockDim.x;
    unsigned long liXPos = threadIdx.x+blockIdx.x*blockDim.x;
    unsigned long liYPos = (threadIdx.y+blockIdx.y*blockDim.y);

    //Check if it is in image bounds
    if(liXPos>=liImageWidth || liYPos>=liImageHeight) return;
    unsigned long liPPos = liXPos+liYPos*liImageWidth;

    //If Boolean is true
    if(lbBool[liPPos]) 
    {
        spID[tid] = _CCL_SHARED_MEM_MAX_VALUE;      
        lpOut[liPPos] =liImageWidth*liImageHeight;
        return;
    }
    lpOut = &lpOut[liPPos];
    lpOut[0] = (blockIdx.x+blockIdx.y*gridDim.x)*(_CCL_SHARED_MEM_MAX_VALUE+1);

    spID[tid] = tid;
    __syncthreads();

    //More Processing Goes Here

    lpOut[0] += static_cast<tOut>(spID[tid]);
}

这应该在lbBool true的等效位置输出255或0吗? 如果它为零,这个Cuda是否优化了对共享内存的写入? 有没有办法让布尔检查将值设置为255?

1 个答案:

答案 0 :(得分:1)

您的共享内存分配已损坏。 __shared__ float lbSpecific;分配一个浮点值。然后,将spID设置为该地址,并使用远远超出单浮点分配的位置。

只需使用正确的大小和类型分配所需的共享内存,然后跳过类型转换。

__shared__ _CCL_SHARED_MEM_TYPE spID[TOTAL_BLOCK_SIZE];