在我的笔记本电脑上(ubuntu.14 + gcc-5.x),我有AVX:
~> 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
我不明白循环是否真的&#34;真的&#34;消息说,矢量化! 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
最后,我得到了&#34; vadd s d&#34; (whit a&#34; v&#34;这似乎代表&#34;矢量化&#34;)但我没有&#34;添加 p d&#34;我原以为是?...
我的理解是&#34;添加 s d&#34;是标量加法(= 1个常规加法),并且&#34;添加 p d&#34;包装添加(=在1个循环中矢量化的几个添加物)。此外,我不明白&#34; v 添加 s d&#34;与&#34;添加 p d&#34; :这些应该是一样的吗? (谷歌这没有给出相关答案)
为什么我没有得到&#34; addpd&#34; ?缺少编译选项?代码中缺少提示/编译指示?或者是合乎逻辑的,如果是的话为什么?
FH
更新
消息说它已被矢量化,但事实并非如此,我没有加速:
~> 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-math(或包含-ffast-math的-Ofast):
~> 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)
addsd
和addpd
是传统的SSE2 SIMD insn。 vaddsd
和vaddpd
是较新的AVX SIMD insn。 this page似乎提供了两者之间的良好比较:它是一种更灵活的编码,具有更高的精度。