我希望能夠幫助優化程序中計算最密集的功能。 目前,我發現基本(非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 –