Come utilizzare le istruzioni Fused Multiply-Add (FMA) con SSE / AVX

Ho appreso che alcune CPU Intel / AMD possono moltiplicare e aggiungere simultaneamente con SSE / AVX:
FLOP per ciclo per sandy-bridge e haswell SSE2 / AVX / AVX2 .

Mi piace sapere come farlo al meglio nel codice e voglio anche sapere come è fatto internamente nella CPU. Intendo con l’architettura super-scalare. Diciamo che voglio fare una lunga sum come la seguente in SSE:

//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (eg 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)); ... 

La mia domanda è: come viene convertito in simultaneo moltiplicare e aggiungere? I dati possono essere dipendenti? Voglio dire, la CPU può fare _mm_add_ps(sum, _mm_mul_ps(a1, b1)) simultaneamente o fare i registri usati nella moltiplicazione e aggiungere devono essere indipendenti?

Infine, come si applica alla FMA (con Haswell)? _mm_add_ps(sum, _mm_mul_ps(a1, b1)) automaticamente convertito in una singola istruzione FMA o micro-operazione?