Даже не глядя на сборку, я могу сразу сказать, что узкое место связано с доступом к памяти из 4 элементов и с операциями упаковки _mm_set_epi32
. Внутренне, _mm_set_epi32
, в вашем случае, вероятно, будет реализовано как серия unpacklo/hi
инструкций.
Большая часть "работы" в этом цикле заключается в упаковке этих 4 обращений к памяти. В отсутствие SSE4.1 я бы сказал, что цикл может быть быстрее не векторным, а развернутым.
Если вы хотите использовать SSE4.1, вы можете попробовать это. Это может быть быстрее, это не так:
int* logSumArray = (int*)(&logSumVector);
__m128i valuesToXor = _mm_cvtsi32_si128(expTable[*(logSumArray++)]);
valuesToXor = _mm_insert_epi32(valuesToXor, expTable[*(logSumArray++)], 1);
valuesToXor = _mm_insert_epi32(valuesToXor, expTable[*(logSumArray++)], 2);
valuesToXor = _mm_insert_epi32(valuesToXor, expTable[*(logSumArray++)], 3);
Я предлагаю развернуть цикл как минимум на 4 итерации и перемежать все инструкции, чтобы дать этому коду шанс на хорошую работу.
Что вам действительно нужно, так это инструкции Intel AVX2 по сбору / рассеянию. Но это через несколько лет ...