对于sm_20,CUDA编译器不会优化乘以零

时间:2012-12-29 15:16:28

标签: optimization compilation cuda

我有以下(减少测试用例!)CUDA内核

__global__
void test(int n, const double* __restrict__ in, double* __restrict__ out)
{
    int idx = blockIdx.x * blockDim.x * threadIdx.x;

    if (idx < n)
    {
        out[idx] = 0.0*in[idx] + 1.0;
    }
}

我希望生成相当于out[idx] = 1.0的代码。 (当使用模板引擎自动生成内核时会出现0.0*in[idx]之类的非操作表达式,其中0.0的生命为${template_parameter}。但是,nvcc -arch sm_20 -ptx ...生成:< / p>

//
// Generated by NVIDIA NVVM Compiler
// Compiler built on Sat Sep 22 01:35:14 2012 (1348274114)
// Cuda compilation tools, release 5.0, V0.2.1221
//

.version 3.1
.target sm_20
.address_size 64

[...]

    mul.wide.s32    %rd5, %r1, 8;
    add.s64     %rd6, %rd2, %rd5;
    ld.global.f64   %fd1, [%rd6];
    fma.rn.f64  %fd2, %fd1, 0d0000000000000000, 0d3FF0000000000000;
    add.s64     %rd7, %rd1, %rd5;
    st.global.f64   [%rd7], %fd2;

有明确的全球负荷和FMA。然而,当为{0}指定-arch sm_10时,它会生成预期的out[idx] = 1.0代码。是否有任何编译器选项/标志可以诱导它执行上述优化?

1 个答案:

答案 0 :(得分:2)

由于CUDA通常遵循IEEE-754语义,因此未优化浮点乘以零。特别地,IEEE-754规定+ -0 * + -infinity = NaN,+ -0 * NaN = NaN,+ 0 * -0 = -0。有关浮点表达式的此转换和其他转换,请参阅C99标准的“F.8.2表达式转换”一节。