SSE指令在哪里优于正常指令

pyt*_*nic 6 c sse x86-64

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];
Run Code Online (Sandbox Code Playgroud)

有没有办法我可以一次性传递所有4个整数,我的意思是一次性传递整个128个字节pa?并分配res.m128i_i32po一气呵成?

Mys*_*ial 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问题的一些示例.