尝试在64位数据类型上运行简单的模板化内核时cudaErrorLaunchFailure

时间:2014-01-09 09:40:13

标签: c++ cuda

我有这个简单的内核代码:

template<typename T> __global__ void CalcHamming( const T* pData, const uint64_t u64Count, const T Arg, uint32_t* pu32Results )
{
    uint64_t gidx = blockDim.x * blockIdx.x + threadIdx.x;

    while ( gidx < u64Count )
    {
        pu32Results[ gidx ] += __popc( pData[gidx] ^ Arg );
        gidx += blockDim.x * gridDim.x;
    }
}

除非我将它用于64位无符号整数(uint64_t),否则它可以正常工作。在那种情况下,我得到 cudaErrorLaunchFailure 。我想可能问题出在 __ popc()中,它无法处理64位数字所以我做了一个专门的函数来解决这个问题:

template<> __global__ void CalcHamming<uint64_t>( const uint64_t* pData, const uint64_t u64Count, const uint64_t Arg, uint32_t* pu32Results )
{
    uint64_t gidx = blockDim.x * blockIdx.x + threadIdx.x;

    while ( gidx < u64Count )
    {
        pu32Results[ gidx ] += __popcll( pData[gidx] ^ Arg );
        gidx += blockDim.x * gridDim.x;
    }
}

但问题仍然存在。需要注意的一点是,我的数据不在几个数组中,如下所示:

Array1(uint32_t):100个项目
Array2(uint64_t):200项

但改为在一个内存块中连接:

数组:100项(uint32_t),200项(uint64_t)

我正在做一些指针运算来在正确的位置启动内核。我很确定计算是正确的。另请注意,上面的示例是一个简化的情况,我有更多的“子阵列”,各种整数类型连接起来这样)。

我的猜测是,这可能是问题的背后,CUDA不知何故不喜欢uint64_t数组的对齐。然而,修复它需要相当多的努力,我希望在我做之前确保它会有所帮助。或者我可以通过某种方式修改内核来解决这个问题吗?是否会有性能损失?

1 个答案:

答案 0 :(得分:1)

uint64_t 必须为8字节对齐:请参阅HERE

所以是的,CUDA“不喜欢”未对齐的类型:它根本不与它们一起运行。

但是我认为您可以避免在外部重新安排数据结构。你足以检查和处理uint32_t(或uint8_t的总体通用性!)数组的极值。这在优化的内核中很常见,特别是使用float4,int4,...等矢量类型

对于某些对齐提示,请参阅HERE