我正在使用 SSE 内在函数为 Intel x86 Nehalem 微架构优化一些代码。
我的程序的一部分计算 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 寄存器中,相对于其他临时 xmm 寄存器,结果被放入一个唯一的 32 位中,因此最终结果如下所示:
tmp0= R0-零-零-零
tmp1= 零-R1-零-零
tmp2= 零-零-R2-零
tmp3=零-零-零-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);
我想知道是否有一种不那么迂回、更有效的方法来获取点积的结果并将它们添加到数组的连续块中。这样,我在其中只有 1 个非零值的寄存器之间进行了 3 次加法。似乎应该有一种更有效的方法来解决这个问题。
我感谢所有帮助。谢谢你。