I am trying to understand if is advantageous using std::fma with double arguments by looking at the assembly code that is generated, I am using the flag "-O3", and I am comparing the assembly for this two routines:
#include <cmath>
#define FP_FAST_FMAF
float test_1(const double &a, const double &b, const double &c ){
return a*b + c;
}
float test_2(const double &a, const double &b, const double &c ){
return std::fma(a,b,c);
}
Using the Compiler Explorer tools, this is the assembly generated for the two routines:
test_1(double const&, double const&, double const&):
movsd xmm0, QWORD PTR [rdi] #5.12
mulsd xmm0, QWORD PTR [rsi] #5.14
addsd xmm0, QWORD PTR [rdx] #5.18
cvtsd2ss xmm0, xmm0 #5.18
ret #5.18
test_2(double const&, double const&, double const&):
push rsi #7.65
movsd xmm0, QWORD PTR [rdi] #8.12
movsd xmm1, QWORD PTR [rsi] #8.12
movsd xmm2, QWORD PTR [rdx] #8.12
call fma #8.12
cvtsd2ss xmm0, xmm0 #8.12
pop rcx #8.12
ret
And the assembly does not change by using the latest version available for either icc or gcc. what is puzzling for me regarding the performance of the two routines is that, while for test_1 there is only one memory operation ( movsd ), there are three for test_2, and considering the latency for memory operations is between one and two orders of magnitude larger than the latency for floating-point operations, test_1 shall be more performant. Thus, in which situations is advisable using std::fma? What is mistaken in my hypothesis?