【发布时间】:2011-05-25 21:45:28
【问题描述】:
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.
}
上面提到的代码在我的程序中被多次调用(profiler显示98%)。
编辑:在内部循环中, res1[i + k] 值会为相同的 (i + k) 值加载多次。我在 while 循环中尝试了这个,我将所有 res1 值加载到 simd 寄存器(数组)中,并在最里面的 for 循环中使用数组元素来更新数组元素。完成两个 for 循环后,我将数组值存储回 res1、re2。但是计算时间随之增加。知道我哪里错了吗?这个想法似乎是正确的
欢迎任何使其更快的建议。
【问题讨论】:
-
这段代码应该做什么?您如何处理数据局部性问题(根据我的经验,这是优化中最重要的部分)?
-
每次迭代res1,res2变量都会和_mulpre进行异或(移位(u1,u2)),然后res1,res2都左移4位
-
res1, res2, _mulpre都是局部变量,连续访问
-
你实际测试过这段代码吗?只是看起来你正在尝试做错位和存储? [或者 unsigned long 在您的系统上可能是 64 位(在这种情况下,您可能希望使用 uint64_t 来代替,以避免混淆)。]
-
@anup: 好的 - 我建议你使用
中的类型以避免混淆。
标签: c optimization sse simd sse2