Я оптимизирую код для микроархитектуры Intel x86 Nehalem, используя встроенные функции SSE.
Часть моей программы вычисляет 4 точечных продукта и добавляет каждый результат к предыдущим значениям в смежном фрагменте массива. Более конкретно,
tmp0 = _mm_dp_ps(A_0m, B_0m, 0xF1);
tmp1 = _mm_dp_ps(A_1m, B_0m, 0xF2);
tmp2 = _mm_dp_ps(A_2m, B_0m, 0xF4);
tmp3 = _mm_dp_ps(A_3m, B_0m, 0xF8);
tmp0 = _mm_add_ps(tmp0, tmp1);
tmp0 = _mm_add_ps(tmp0, tmp2);
tmp0 = _mm_add_ps(tmp0, tmp3);
tmp0 = _mm_add_ps(tmp0, C_0n);
_mm_storeu_ps(C_2, tmp0);
Обратите внимание, что я об этом говорю, используя 4 временных регистра xmm для хранения результата каждого точечного продукта. В каждом регистре xmm результат помещается в уникальные 32 бита относительно других временных регистров xmm, так что конечный результат выглядит следующим образом:
tmp0 = R0-zero-zero-zero
tmp1 = zero-R1-zero-zero
tmp2 = zero-zero-R2-zero
tmp3 = zero-zero-zero-R3
Я объединяю значения, содержащиеся в каждой переменной tmp, в одну переменную xmm, суммируя их со следующими инструкциями:
tmp0 = _mm_add_ps(tmp0, tmp1);
tmp0 = _mm_add_ps(tmp0, tmp2);
tmp0 = _mm_add_ps(tmp0, tmp3);
Наконец, я добавляю регистр, содержащий все 4 результата точечных произведений, в смежную часть массива, так что индексы массива увеличиваются на точечный продукт, так же (C_0n - это 4 значения, которые в настоящее время находятся в массиве, который равен для обновления, C_2 - адрес, указывающий на эти 4 значения):
tmp0 = _mm_add_ps(tmp0, C_0n);
_mm_storeu_ps(C_2, tmp0);
Я хочу знать, существует ли менее эффективный и эффективный способ получения результатов точечных продуктов и добавления их в смежный кусок массива. Таким образом, я делаю 3 дополнения между регистрами, в которых есть только 1 ненулевое значение. Кажется, должен быть более эффективный способ сделать это.
Я ценю всю помощь. Спасибо.