Optimization CUDA编译器未优化sm_20的乘零运算

Optimization CUDA编译器未优化sm_20的乘零运算,optimization,compilation,cuda,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; } } 有明确的全球负荷和FMA的地方

我有以下(简化的测试用例!)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;
    }
}

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

浮点零乘法没有优化,因为CUDA通常遵循IEEE-754语义。具体而言,IEEE-754规定+-0*+-infinity=NaN、+-0*NaN=NaN和+0*-0=-0。请参阅C99标准的“F.8.2表达式转换”部分,了解浮点表达式的此转换和其他转换。

是否尝试使用-O3标志启用优化?对于CC 2.0编译器,NVIDIA从GCC切换到LLVM。也许这种优化不在LLVM中。首先,这只是PTX,所以汇编程序仍然有可能消除乘零运算。但话说回来,消除乘法并不是一种优化——双精度FMAD和双精度MUL指令在费米上的周期数完全相同……@talonmies消除乘法为消除减少内存带宽的负载铺平了道路。因此,我想知道是否有类似于-GCC的ffast math或ICC的默认值禁用此类语义。据我所知,nvcc提供了一个标志-use_fast_math,但它只影响单精度计算,主要影响操作替换,而不是IEEE-754语义的放松。一般来说,IEEE-754语义提供了有用的属性,可以增强浮点计算的健壮性。CUDA数学库(目前作为头文件中的内联函数集合提供)依赖于IEEE-754语义。
//
// 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;