gcc 4.8 AVX优化缺陷:额外代码插入?

gcc 4.8 AVX优化缺陷:额外代码插入?,gcc,optimization,g++,sse,avx,Gcc,Optimization,G++,Sse,Avx,gcc编译器4.8带有AVX优化和-Ofast选项,这非常棒。然而,我发现了一个有趣但愚蠢的错误,它增加了不必要的额外计算。也许我错了,有人能给我解释一下吗 原始的C++源代码如下: #define N 1000007 float a[N],b[N],c[N],d[N],e[N]; int main(int argc, char *argv[]){ cout << a << ' ' << b << ' ' << c <

gcc编译器4.8带有AVX优化和-Ofast选项,这非常棒。然而,我发现了一个有趣但愚蠢的错误,它增加了不必要的额外计算。也许我错了,有人能给我解释一下吗

<>原始的C++源代码如下:

#define N 1000007

float a[N],b[N],c[N],d[N],e[N];

int main(int argc, char *argv[]){
    cout << a << ' ' << b << ' ' << c << endl;
    for(int x=0; x<N; ++x){
        c[x] = 1/sqrt((a[x]+b[x]-c[x])*d[x]/e[x]);
    }
    return  0;
}
  90                    .LVL10:
  91 006b C5FC2825              vmovaps ymm4, YMMWORD PTR .LC0[rip]
  91      00000000 
  92 0073 31C0                  xor     eax, eax
  93 0075 C5FC281D              vmovaps ymm3, YMMWORD PTR .LC1[rip]
  25:avx.cpp       ****         for(int x=0; x<N; ++x){
  26:avx.cpp       ****                 c[x] = 1/sqrt((a[x]+b[x]-c[x])*d[x]/e[x]);
 101                            .loc 1 26 0 discriminator 2
 102 0080 C5FC2890              vmovaps ymm2, YMMWORD PTR b[rax]
 102      00000000 
 103 0088 4883C020              add     rax, 32
 104 008c C5FC2888              vmovaps ymm1, YMMWORD PTR e[rax-32]
 104      00000000 
 105 0094 C5EC5890              vaddps  ymm2, ymm2, YMMWORD PTR a[rax-32]
 105      00000000 
 106 009c C5FC53C1              vrcpps  ymm0, ymm1
 107 00a0 C5FC59C9              vmulps  ymm1, ymm0, ymm1
 108 00a4 C5FC59C9              vmulps  ymm1, ymm0, ymm1
 109 00a8 C5EC5C90              vsubps  ymm2, ymm2, YMMWORD PTR c[rax-32]
 109      00000000 
 110 00b0 C5FC58C0              vaddps  ymm0, ymm0, ymm0
 111 00b4 C5EC5990              vmulps  ymm2, ymm2, YMMWORD PTR d[rax-32]
 111      00000000 
 112 00bc C5FC5CC9              vsubps  ymm1, ymm0, ymm1
 113 00c0 C5EC59C1              vmulps  ymm0, ymm2, ymm1
 118 00c4 C5FC52C8              vrsqrtps        ymm1, ymm0
 119 00c8 C5F459C0              vmulps  ymm0, ymm1, ymm0
 120 00cc C5FC59C1              vmulps  ymm0, ymm0, ymm1
 121 00d0 C5F459CB              vmulps  ymm1, ymm1, ymm3
 122 00d4 C5FC58C4              vaddps  ymm0, ymm0, ymm4
^LGAS LISTING /tmp/ccJtIFtg.s                   page 21


 123 00d8 C5FC59C9              vmulps  ymm1, ymm0, ymm1
 124                    .LBE45:
 125                    .LBE44:
 126                            .loc 1 26 0 discriminator 2
 127 00dc C5FC2988              vmovaps YMMWORD PTR c[rax-32], ymm1
 127      00000000 
 128 00e4 483D0009              cmp     rax, 4000000
 128      3D00
 129 00ea 7594                  jne     .L3
#定义N 1000007
浮点数a[N]、b[N]、c[N]、d[N]、e[N];
int main(int argc,char*argv[]){

cout我认为您在生成的代码中看到的是一个额外的迭代,用于细化
vrcpps
提供的初始估计值(有关
vrcpps
提供的初始估计值的准确性的详细信息,请参见:的)

我已经弄明白了原因。所有AVX/SIMD/SSE近似指令都需要至少一次Newton-Rhapson迭代来恢复精度,否则,它将失去50%的精度,即原始FLOAT32的精度高达23位。没有任何Newton-Rhapson,我们只剩下11位精度。这种近似太粗糙了,无法直接使用可用。

使用
g++-Ofast-S-fverbose asm-fdump tree all
编译,查看生成的
.S
文件,以了解更多关于优化的信息;顺便说一句,您的GCC非常旧,当前的GCC在2016年1月初。是的,这就是GCC正在做的。它与。