Как использовать инструкции Fused Multiply-Add (FMA) с SSE / AVX

Я узнал, что некоторые процессоры Intel / AMD могут выполнять одновременное умножение и добавление с помощью SSE / AVX:

FLOPS за цикл для песчаного моста и скважины SSE2 / AVX / AVX2.

Мне нравится знать, как сделать это лучше всего в коде, и я также хочу знать, как этосделано внутри процессора. Я имею в виду суперскалярную архитектуру. Позволять'скажем, я хочу сделать длинную сумму, такую как следующее в SSE:

//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));
...

Мой вопрос: как это преобразуется в одновременное умножение и сложение? Могут ли данные быть зависимыми? Я имею в виду процессор может сделать_mm_add_ps(sum, _mm_mul_ps(a1, b1)) одновременно или регистры, используемые в умножении и сложении, должны быть независимыми?

Наконец, как это относится к FMA (с Haswell)? Является_mm_add_ps(sum, _mm_mul_ps(a1, b1)) автоматически конвертируется в одну инструкцию FMA или микрооперацию?

Ответы на вопрос(2)

Ваш ответ на вопрос