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指令来优化代码,或者你认为我会必须要编译器或代码?
感谢朱晓雷的提示,我现在知道 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 弹出一次(因此它不会展开循环)。