我希望能够帮助优化程序中计算最密集的功能。 目前,我发现基本(非SSE)版本显着更快(最多3倍)。因此,我会请求你帮忙纠正这一情况。优化SSE代码
函数查找无符号整数向量中的子集,并报告它们是否存在。为了您的方便,我只包含了相关的代码片段。
首先是基本变体。它检查block_是否是x.blocks_的一个子集。
//Check for self comparison
if (this == &x)
return false;
//A subset is equal to or smaller.
if (no_bits_ > x.no_bits_)
return false;
int i;
bool equal = false;
//Pointers should not change.
const unsigned int *tptr = blocks_;
const unsigned int *xptr = x.blocks_;
for (i = 0; i < no_blocks_; i++, tptr++, xptr++) {
if ((*tptr & *xptr) != *tptr)
return false;
if (*tptr != *xptr)
equal = true;
}
return equal;
接着是上证所的变体,其中唉根据我的期望不执行。这两个片段都应该寻找相同的东西。
//starting pointers.
const __m128i* start = (__m128i*)&blocks_;
const __m128i* xstart = (__m128i*)&x.blocks_;
__m128i block;
__m128i xblock;
//Unsigned ints are 32 bits, meaning 4 can fit in a register.
for (i = 0; i < no_blocks_; i+=4) {
block = _mm_load_si128(start + i);
xblock = _mm_load_si128(xstart + i);
//Equivalent to (block & xblock) != block
if (_mm_movemask_epi8(_mm_cmpeq_epi32(_mm_and_si128(block, xblock), block)) != 0xffff)
return false;
//Equivalent to block != xblock
if (_mm_movemask_epi8(_mm_cmpeq_epi32(block, xblock)) != 0xffff)
equal = true;
}
return equal;
对于如何改进SSE版本的性能,您有什么建议吗?难道我做错了什么?或者,这是否应该在其他地方进行优化?
我还没有在剩余的计算中加入no_blocks_%4!= 0,但是这样做的目的很小,直到性能提高为止,并且它只会使代码在这一点上混乱起来。
谢谢你提供的任何帮助。
您是否真的了解了编译器为两种情况生成的内容。我发现GCC/G ++首先生成相当不错的SSE代码(并且它更好地避免了我们人类倾向于提出的“寄存器依赖性”)。 –
http://channel9.msdn.com/Events/Build/2013/4-329 –