当前位置:  开发笔记 > 编程语言 > 正文

使用SSE指令

如何解决《使用SSE指令》经验,为你挑选了4个好方法。

我有一个用C++编写的循环,它是为一个大整数数组的每个元素执行的.在循环内部,我屏蔽了整数的一些位,然后找到最小值和最大值.我听说如果我使用SSE指令进行这些操作,它将比使用按位AND和if-else条件写入的普通循环运行得快得多.我的问题是我应该参加这些SSE指令吗?此外,如果我的代码在不同的处理器上运行会发生什么?它仍然可以工作或这些指令是特定于处理器的吗?



1> Niki..:

    SSE指令是特定于处理器的.您可以在维基百科上查找哪个处理器支持哪个SSE版本.

    如果SSE代码更快或更快取决于许多因素:第一个当然是问题是内存限制还是CPU限制.如果内存总线是瓶颈,SSE将无济于事.尝试简化整数计算,如果这使得代码更快,它可能受CPU限制,并且您很有可能加快它的速度.

    请注意,编写SIMD代码比编写C++代码困难得多,并且生成的代码更难以更改.始终保持C++代码是最新的,您需要将其作为注释并检查汇编代码的正确性.

    考虑使用像IPP这样的库,它实现了针对各种处理器优化的常见低级SIMD操作.


"如果内存总线是瓶颈,SSE将无济于事." - 这是无视流式内存操作.

2> Skizz..:

以SSE为例的SIMD允许您对多个数据块执行相同的操作.因此,使用SSE作为整数运算的直接替换将不会有任何好处,只有您可以同时对多个数据项执行操作时才会获得优势.这涉及加载一些在内存中连续的数据值,执行所需的处理,然后单步执行数组中的下一组值.

问题:

1如果代码路径依赖于正在处理的数据,则SIMD变得更难实现.例如:

a = array [index];
a &= mask;
a >>= shift;
if (a < somevalue)
{
  a += 2;
  array [index] = a;
}
++index;

像SIMD一样不容易做到:

a1 = array [index] a2 = array [index+1] a3 = array [index+2] a4 = array [index+3]
a1 &= mask         a2 &= mask           a3 &= mask           a4 &= mask
a1 >>= shift       a2 >>= shift         a3 >>= shift         a4 >>= shift
if (a1

2如果数据不重要,则将数据加载到SIMD指令中是很麻烦的

3代码是特定于处理器的.SSE仅适用于IA32(Intel/AMD),并非所有IA32 cpus都支持SSE.

您需要分析算法和数据以查看它是否可以进行SSE并且需要了解SSE的工作原理.英特尔网站上有大量文档.


问题1通常使用SIMD掩码指令来解决.像__m128 mask = _mm_cmplt_ps(a,somevalue); a = _mm_add_ps(a,_mm_and_ps(mask,_ mm_set_ps1(2));对于if(a
3> 小智..:

这种问题是良好的低级分析器必不可少的完美例子.(像VTune这样的东西)它可以让你更加了解你的热点所在的位置.

我的猜测,从你描述的是你的热点可能是使用if/else计算最小/最大值导致的分支预测失败.因此,使用SIMD内在函数应该允许您使用最小/最大指令,但是,尝试使用无分支最小/最大计算可能是值得的.这可以通过减少痛苦来实现大部分收益.

像这样的东西:

inline int 
minimum(int a, int b)
{
  int mask = (a - b) >> 31;
  return ((a & mask) | (b & ~mask));
}



4> jalf..:

如果您使用SSE指令,则显然仅限于支持这些指令的处理器.这意味着x86,可以追溯到Pentium 2左右(不记得确切的时候它们被引入,但是很久以前)

SSE2,据我所知,是提供整数运算的,有点近一些(Pentium 3?虽然第一款AMD Athlon处理器不支持它们)

在任何情况下,您都有两种使用这些说明的选项.要么在汇编中编写整个代码块(可能是一个坏主意.这使得编译器几乎不可能优化代码,并且人类很难编写高效的汇编程序).

或者,使用编译器可用的内在函数(如果内存服务,它们通常在xmmintrin.h中定义)

但同样,性能可能无法提高.SSE代码对其处理的数据提出了额外的要求.主要是要记住的是数据必须在128位边界上对齐.加载到同一寄存器中的值之间也应该存在很少或没有依赖关系(128位SSE寄存器可以容纳4个整数.将第一个和第二个加在一起并不是最佳的.但是将所有四个整数添加到相应的4个整数中另一个注册会很快)

使用包含所有低级SSE摆弄的库可能很诱人,但这也可能会破坏任何潜在的性能优势.

我不知道SSE的整数运算支持有多好,所以这也可能是一个可以限制性能的因素.SSE主要针对加速浮点运算.

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有