int u1, u2;
unsigned long elm1[20], _mulpre[16][20], res1[40], res2[40]; 64 bits long
res1, res2 initialized to zero.

l = 60;
while (l)
{
    for (i = 0; i < 20; i += 2)
    {
        u1 = (elm1[i] >> l) & 15;
        u2 = (elm1[i + 1] >> l) & 15;

        for (k = 0; k < 20; k += 2)
        {
            simda = _mm_load_si128 ((__m128i *) &_mulpre[u1][k]);
            simdb = _mm_load_si128 ((__m128i *) &res1[i + k]);
            simdb = _mm_xor_si128  (simda, simdb);
            _mm_store_si128 ((__m128i *)&res1[i + k], simdb);

            simda = _mm_load_si128 ((__m128i *)&_mulpre[u2][k]);
            simdb = _mm_load_si128 ((__m128i *)&res2[i + k]);
            simdb = _mm_xor_si128  (simda, simdb);
            _mm_store_si128 ((__m128i *)&res2[i + k], simdb);
        }
    }
    l -= 4;
    All res1, res2 values are left shifted by 4 bits.
}


上面提到的代码在我的程序中被多次调用(分析器显示98%)。

编辑:在内部循环中,对于相同的(i + k)值,res1 [i + k]值被加载多次。我在while循环中对此进行了尝试,将所有res1值加载到simd寄存器(数组)中,并在最里面的for循环内使用数组元素来更新数组元素。一旦两个for循环都完成,我就将数组值存储回res1,re2。但是计算时间随之增加。知道我错了吗?这个想法似乎是正确的

任何建议使其更快。

最佳答案

不幸的是,最明显的优化可能已经由编译器完成:


您可以拉&_mulpre[u1]&mulpre[u2]内部循环。
您可以拉&res1[i]我们的内循环。
对两个内部操作使用不同的变量,并对它们重新排序,可能会更好地进行流水线处理。


可能地交换外部循环将改善elm1上的缓存局部性。

10-06 05:15