我有一个用C++编写的循环,它对一个大整数数组的每个元素执行。在循环中,我屏蔽了整数的一些位,然后找到最小值和最大值。我听说如果我对这些操作使用SSE指令,它将比使用按位AND和if-else条件编写的普通循环运行得快得多。我的问题是,我是否应该使用这些SSE说明?另外,如果我的代码在不同的处理器上运行,会发生什么?它还能工作吗?或者这些指令是特定于处理器的?
发布于 2009-02-25 16:09:33
发布于 2009-02-25 16:24:24
SIMD (以SSE为例)允许您对多个数据块执行相同的操作。因此,使用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<somevalue) if (a2<somevalue) if (a3<somevalue) if (a4<somevalue)
// help! can't conditionally perform this on each column, all columns must do the same thing
index += 42如果数据不是连续的,那么将数据加载到SIMD指令中是很麻烦的
3代码是特定于处理器的。SSE仅在IA32 (英特尔/AMD)上,并不是所有的IA32 cpus都支持SSE。
你需要分析算法和数据,看看它是否可以进行SSE,这需要知道SSE是如何工作的。英特尔的网站上有大量的文档。
发布于 2009-02-26 16:19:09
这类问题是一个很好的例子,说明了一个好的低级分析器是必不可少的。(类似于VTune)它可以让你对你的热点位置有更多的了解。
我猜测,根据您的描述,您的热点可能是由于使用if/else进行最小/最大计算而导致的分支预测失败。因此,使用SIMD内部函数应该允许您使用min/max指令,但是,尝试使用无分支min/max计算可能是值得的。这可能会以较少的痛苦获得大部分收益。
如下所示:
inline int
minimum(int a, int b)
{
int mask = (a - b) >> 31;
return ((a & mask) | (b & ~mask));
}https://stackoverflow.com/questions/586609
复制相似问题