2016-03-08 95 views
0

在我的筆記本電腦(ubuntu.14 + GCC-5.x的),我有AVX:簡單的循環:矢量化用gcc

~> tail /proc/cpuinfo 
    model name : Intel(R) Core(TM) i7-3687U CPU @ 2.10GHz 
    flags  : ... sse sse2 ... avx 

我編譯這個非常簡單的代碼:

~> more test.c 
    #include <stdio.h> 
    void main() { 
    int i=0; double a=1.; 
    for(i=0;i<1000000;i++) a+=i; 
    printf("%f\n", a); // printf: avoid compiler optim (dummy var suppression) 
    } 
~> make 
    gcc -O2 -march=native -mavx -ftree-vectorize -funroll-loops -fopt-info-vec -fopt-info-loop -o test.exe test.c 
    test.c:4:3: note: loop unrolled 7 times 

我不明白,如果循環被「真正」向量化爲消息說! objdump的講述:

~> objdump -S test.exe | grep add 
    40041d: 48 83 c4 08    add $0x8,%rsp 
    4004a9: c5 fb 58 c2    vaddsd %xmm2,%xmm0,%xmm0 
    4004b8: c5 fb 58 ec    vaddsd %xmm4,%xmm0,%xmm5 
    4004cb: c5 53 58 c7    vaddsd %xmm7,%xmm5,%xmm8 
    4004e1: c4 41 3b 58 da   vaddsd %xmm10,%xmm8,%xmm11 
    4004ea: 83 c0 08    add $0x8,%eax 
    4004f2: c4 41 23 58 f5   vaddsd %xmm13,%xmm11,%xmm14 
    4004f7: c5 8b 58 d1    vaddsd %xmm1,%xmm14,%xmm2 
    4004fb: c5 eb 58 e3    vaddsd %xmm3,%xmm2,%xmm4 
    4004ff: c5 db 58 c6    vaddsd %xmm6,%xmm4,%xmm0 
    4005bb: 48 01 c6    add %rax,%rsi 
    40067d: 48 83 c3 01    add $0x1,%rbx 
    400686: 48 83 c4 08    add $0x8,%rsp 
    4006a8: 48 83 c4 08    add $0x8,%rsp 

所以最後,我得到「VADD 小號 d」(白衣似乎代表「矢量化」一個「V」),但我沒有「添加p d」我本來期望?...

我的理解是,「增加小號 d」是標量增加(= 1規律的添加),而且「加p d」包裝除了(=幾的添加矢量化在1個週期中)。此外,我不明白什麼「vs d」是不同於「add p d」:這些應該是相同的? (谷歌這並不給出相關的答案)

爲什麼我不會得到「addpd」?缺少編譯選項?代碼中缺少提示/編譯指示?或者是邏輯的,如果是的話,爲什麼?

FH

UPDATE

有消息稱,已經向量化,但它不是,我沒有得到任何加速:

~> more test.c 
    #include <stdio.h> 
    void main() { 
    unsigned int i=0; double a=1.; 
    for(i=0;i<3000000000;i++) a+=i; 
    printf("%f\n", a); // printf : avoid compiler optimisation what suppress a as it's a dummy variable ! 
    } 
~> make 
    gcc -O2 -march=native -o test.novec.exe test.c 
    gcc -O2 -march=native -mavx -ftree-vectorize -funroll-loops -fopt-info-vec -fopt-info-loop -o test.vec.exe test.c 
    test.c:4:3: note: loop unrolled 7 times 
~> time ./test.novec.exe 
    4499999997067113984.000000 
    real 0m2.927s 
    user 0m2.928s 
    sys 0m0.000s 
~> time ./test.vec.exe 
    4499999997067113984.000000 
    real 0m2.926s 
    user 0m2.924s 
    sys 0m0.000s 

...除非我添加-ffast-數學(或-Ofast,包括-ffast-math):

~> make 
    gcc -O2 -march=native -mavx -ftree-vectorize -funroll-loops -fopt-info-vec -fopt-info-loop -ffast-math -o test.vec.fm.exe test.c 
    test.c:4:3: note: loop vectorized 
    test.c:4:30: note: loop unrolled 3 times 
~> time ./test.vec.fm.exe 
    4499999999597346816.000000 
    real 0m1.980s 
    user 0m1.980s 
    sys 0m0.000s 
+0

消息無處說它已被矢量化... –

+0

您希望重新排序浮點數的總和的轉換。爲了安全起見,gcc只有在你告訴它沒問題的時候纔會這樣做(例如 - 安裝數學)。 –

+0

使用'-Ofast'進行編譯,並將向量化(您會看到'vaddpd')。 –

回答

0

addsdaddpd是傳統的SSE2 SIMD insn。 vaddsdvaddpd是較新的AVX SIMD insn。 this page似乎提供了一個很好的比較:這是一個更高的精度更靈活的編碼。