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字节的pa
?并一次性将res.m128i_i32
分配给po
?
答案 0 :(得分:10)
总结回答的评论:
你基本上陷入了大多数第一次接触的陷阱。基本上你的例子有两个问题:
_mm_set_epi32()
。 _mm_set_epi32()
是一种非常昂贵的内在因素。虽然使用起来很方便,但它不能编译成单个指令。使用_mm_set_epi32()
时,某些编译器(如VS2010)可能会生成性能极差的代码。
相反,由于您要加载连续的内存块,因此应使用_mm_load_si128()
。这要求指针对齐16个字节。如果您无法保证此对齐,则可以使用_mm_loadu_si128()
- 但会降低性能。理想情况下,您应该正确对齐数据,以便不需要使用_mm_loadu_si128()
。
使用SSE真正高效,您还需要最大化计算/负载存储比率。我拍摄的目标是每个存储器访问3-4个算术指令。这是一个相当高的比例。通常,您必须重构代码或重新设计算法以增加代码。结合传递数据是一种常见的方法。
当您拥有具有长依赖关系链的大型循环体时,通常需要循环展开以最大化性能。
成功使用SSE实现加速的SO问题的一些例子。