在总结两个数组的乘积时,gfortran或ifort编译器会明智地使用SIMD指令吗?

lnm*_*rer 5 fortran simd gfortran fma intel-fortran

我有一些用numpy编写的代码,我正在考虑将它移植到Fortran以获得更好的性能.

我做过几次的一个操作就是将两个数组的元素乘积相加:

sum(A*B)
Run Code Online (Sandbox Code Playgroud)

看起来融合的乘法 - 加法指令会对此有所帮助.我当前的处理器不支持这些说明,所以我还无法测试.但是,我可能会升级到支持FMA3(Intel Haswell处理器)的新处理器.

有没有人知道用"-march = native"(或ifort等价物)编译程序是否足以让编译器(gfortran或ifort)明智地使用SIMD指令来优化代码,或者你认为我会必须要编译器或代码?

lnm*_*rer 1

感谢朱晓雷的提示,我现在知道 gfortran 将使用融合乘加来优化sum(A*B)。例如,使用以下代码:

程序测试隐式无

实数,维度(7) :: a, b

a = (/ 2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0 /)

b = (/ 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0 /)

print *, sum(a*b)
结束程序

我可以用 编译它f95 sum.f95 -o sum -O3 -march=core-avx2,并objdump -d sum | grep vfmadd显示

40088b: c4 e2 71 99 44 24 30 vfmadd132ss 0x30(%rsp),%xmm1,%xmm0

400892: c4 e2 69 b9 44 24 34 vfmadd231ss 0x34(%rsp),%xmm2,%xmm0

400899: c4 e2 61 b9 44 24 38 vfmadd231ss 0x38(%rsp),%xmm3,%xmm0

4008a0: c4 e2 59 b9 44 24 3c vfmadd231ss 0x3c(%rsp),%xmm4,%xmm0

4008a7: c4 e2 51 b9 44 24 40 vfmadd231ss 0x40(%rsp),%xmm5,%xmm0

4008ae: c4 e2 49 b9 44 24 44 vfmadd231ss 0x44(%rsp),%xmm6,%xmm0

4008b5: c4 e2 41 b9 44 24 48 vfmadd231ss 0x48(%rsp),%xmm7,%xmm0

因此 gfortran 展开循环并放入 7 个融合乘加指令。如果我创建更大的随机多维数组,我仍然会看到 vfmadd231ss 弹出一次(因此它不会展开循环)。