Я бы хотел, чтобы некоторые из них помогли оптимизировать самую вычислительно интенсивную функцию моей программы. В настоящее время я нахожу, что базовая (не SSE) версия значительно быстрее (до 3x). Поэтому я прошу вас помочь в исправлении этого.Оптимизация кода 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;
Затем идет вариант SSE, который, увы, не соответствует моим ожиданиям. Оба эти фрагмента должны искать одни и те же вещи.
//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 –