7

x86-64 的 SSE 指令(向量指令)在哪里优于普通指令。因为我看到的是执行 SSE 指令所需的频繁加载和存储正在抵消我们因向量计算而获得的任何收益。那么有人可以给我一个示例 SSE 代码,它的性能比普通代码更好。

可能是因为我分别传递每个参数,像这样......

__m128i a = _mm_set_epi32(pa[0], pa[1], pa[2], pa[3]);
__m128i b = _mm_set_epi32(pb[0], pb[1], pb[2], pb[3]);
__m128i res = _mm_add_epi32(a, b);

for( i = 0; i < 4; i++ )
 po[i] = res.m128i_i32[i];

有没有一种方法可以一次传递所有 4 个整数,我的意思是一次传递整个 128 个字节pares.m128i_i32并一次性分配po

4

1 回答 1

10

将评论总结为答案:

您基本上落入了与大多数初学者相同的陷阱。您的示例中基本上有两个问题:

  1. 你在滥用_mm_set_epi32().
  2. 您的计算/负载存储比率非常低。(在您的示例中为 1 到 3)

_mm_set_epi32()是一个非常昂贵的内在函数。虽然使用起来很方便,但它不会编译成一条指令。一些编译器(例如 VS2010)在使用_mm_set_epi32().

相反,由于您正在加载连续的内存块,您应该使用_mm_load_si128(). 这要求指针对齐到 16 个字节。如果您不能保证这种对齐,您可以使用_mm_loadu_si128()- 但会降低性能。理想情况下,您应该正确对齐数据,这样就不需要使用_mm_loadu_si128().


要真正高效地使用 SSE,您还需要最大化您的计算/负载存储比率。我的目标是每次内存访问 3 到 4 条算术指令。这是一个相当高的比例。通常,您必须重构代码或重新设计算法以增加它。结合对数据的传递是一种常见的方法。

当您拥有具有长依赖链的大型循环体时,通常需要展开循环以最大限度地提高性能。


一些成功使用 SSE 实现加速的 SO 问题示例。

于 2012-04-25T10:48:12.373 回答