Verwendung der FMA-Anweisungen (Fused Multiply-Add) mit SSE / AVX

Ich habe gelernt, dass einige Intel / AMD-CPUs mit SSE / AVX simultan multiplizieren und addieren können:
FLOPS pro Zyklus für Sandbrücke und Haswell SSE2 / AVX / AVX2.

Ich möchte wissen, wie dies am besten im Code funktioniert, und ich möchte auch wissen, wie dies intern in der CPU erfolgt. Ich meine mit der superskalaren Architektur. Nehmen wir an, ich möchte eine lange Summe wie die folgende in SSE machen:

//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (e.g. from matrix multiplication)
sum = _mm_set1_ps(0.0f);
a1  = _mm_set1_ps(a[0]); 
b1  = _mm_load_ps(&b[0]);
sum = _mm_add_ps(sum, _mm_mul_ps(a1, b1));

a2  = _mm_set1_ps(a[1]); 
b2  = _mm_load_ps(&b[4]);
sum = _mm_add_ps(sum, _mm_mul_ps(a2, b2));

a3  = _mm_set1_ps(a[2]); 
b3  = _mm_load_ps(&b[8]);
sum = _mm_add_ps(sum, _mm_mul_ps(a3, b3));
...

Meine Frage ist, wie dies konvertiert wird, um gleichzeitig zu multiplizieren und zu addieren? Können die Daten abhängig sein? Ich meine, kann die CPU tun_mm_add_ps(sum, _mm_mul_ps(a1, b1)) gleichzeitig oder müssen die bei der Multiplikation und Addition verwendeten Register unabhängig sein?

Wie ist das bei der FMA (mit Haswell)? Ist_mm_add_ps(sum, _mm_mul_ps(a1, b1)) automatisch in eine einzelne FMA-Anweisung oder Mikrooperation konvertiert?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage