CUDA shuffle warp减少不能作为内联设备功能

时间:2016-02-17 14:56:45

标签: cuda

我在warps中做了如下缩小:

__global__ void summation1(double *nBodies)
{

    ...

    for (int offset = warpSize/2; offset > 0; offset /= 2) {
        elements.x += __shfl_down(elements.x, offset);
    }

    ...

}

以上工作正常。然后我接受了代码并将其放在这样的函数中:

__inline__ __device__
double warpReduceSum(double val) {
    for (int offset = warpSize/2; offset > 0; offset /= 2) {
        val += __shfl_down(val, offset);
    }
        return val;
}

__global__ void summation1(double *nBodies)
{

    ...

    warpReduceSum(elements.x);

    ...

}

然而,上述情况不起作用 - 我没有得到一笔钱,只是原来的值。关于为什么会发生这种情况的任何想法都将非常感激。

1 个答案:

答案 0 :(得分:3)

warp shuffle operations 不适用于64位数量。请参阅documentation。例如:

  

必须首先转换int或float以外的类型才能使用__shfl()内在函数。

但是根据您在CUDA标头中使用未记录的函数的注释。我相信它应该有用。

经过进一步考虑后,我认为您遇到的问题是传递价值。对于此函数定义:

__inline__ __device__
double warpReduceSum(double val) {
    for (int offset = warpSize/2; offset > 0; offset /= 2) {
        val += __shfl_down(val, offset);
    }
        return val;
}

您将val按值传递给函数,因此该函数具有该值的本地副本。然后你去减少扭曲。但是在主代码中,您忽略了返回值:

warpReduceSum(elements.x);

实际的混洗值 实际上不是elements.x,而是它的一些副本。

修复可能很简单:

elements.x = warpReduceSum(elements.x);

您也可以尝试按引用传递数量:

double warpReduceSum(double &val) {

我已经测试了这两个建议。任何一个似乎都适用于我的测试用例。

请注意,SO需要一个完整的代码来寻求调试帮助的问题。来自here

  

寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为,特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用。请参阅:如何创建最小,完整且可验证的示例。

因此,如果上述建议没有帮助(即在你回来之前说“我做了那个改变,它没有用”),我会建议一个完整的代码,证明问题是按顺序。