我有两个double
类型的数组,我想执行vecA += vecB
。到目前为止,我正在做vecA = vecA + vecB
,据我所知,例如写入i = i + 5
的整数比i += 5
慢。所以我想知道,是否有一些SSE函数可以在__m128d上仅执行operator+=
。我搜索后什么也没找到。我的应用程序在vecA = vecA + vecB
操作上花费了大约60%的时间,因此任何性能提升都会显示出来。
下面的代码片段中的所有数组都是16字节对齐的,len
始终是偶数。
原始代码很简单
inline void addToDoubleVectorSSE(
const double * what, const double * toWhat, double * dest, const unsigned int len)
{
__m128d * _what = (__m128d*)what;
__m128d * _toWhat = (__m128d*)toWhat;
for ( register unsigned int i = 0; i < len; i+= 2 )
{
*_toWhat = _mm_add_pd( *_what, *_toWhat );
_what++;
_toWhat++;
}
}
在阅读http://fastcpp.blogspot.cz/2011/04/how-to-process-stl-vector-using-sse.html之后,作者通过不立即写他刚刚阅读的内容而获得了表现,因此我尝试了
__m128d * _what = (__m128d*)what;
__m128d * _toWhat = (__m128d*)toWhat;
__m128d * _toWhatBase = (__m128d*)toWhat;
__m128d _dest1;
__m128d _dest2;
for ( register unsigned int i = 0; i < len; i+= 4 )
{
_toWhatBase = _toWhat;
_dest1 = _mm_add_pd( *_what++, *_toWhat++ );
_dest2 = _mm_add_pd( *_what++, *_toWhat++ );
*_toWhatBase++ = _dest1;
*_toWhatBase++ = _dest2;
}
但是速度没有任何改善。那么,
operator+=
是否有任何__m128d
?还是我可以使用其他方法对双精度数组执行operator + =?使用MSVC,目标平台将始终是Intel i7 CPU上的Windows(XP和7)。 最佳答案
据我所知,没有等效的+=
,因为SSE算术运算通常是寄存器到寄存器或内存到寄存器的,而不是寄存器到内存的。
但是,您可以使用链接的博客文章中的建议来提高性能。该技巧对您无效的原因是您没有消除两条指令之间的依赖关系:++
和_what++
中_toWhat++
增量的副作用阻止了第二对操作同时开始。如下修改您的循环以获得改进:
for ( register unsigned int i = 0; i < len; i+= 4, _what += 2, _toWhat += 2, _toWhatBase+=2 )
{
_toWhatBase = _toWhat;
_dest1 = _mm_add_pd( *_what, *_toWhat );
_dest2 = _mm_add_pd( *(_what+1), *(_toWhat+1));
*_toWhatBase = _dest1;
*(_toWhatBase+1) = _dest2;
}
更改后,对
_dest2
的操作变得独立于对_dest1
的操作根据我的挂钟估计,经过简单的修改,我的性能提高了约28%。