Я новичок в программировании SSE, поэтому я надеюсь, что кто-то там может мне помочь. Недавно я реализовал функцию, использующую встроенные функции GCC SSE для вычисления суммы массива из 32-разрядных целых чисел. Код для моей реализации приведен ниже.Более медленная производительность SSE при больших размерах массивов
int ssum(const int *d, unsigned int len)
{
static const unsigned int BLOCKSIZE=4;
unsigned int i,remainder;
int output;
__m128i xmm0, accumulator;
__m128i* src;
remainder = len%BLOCKSIZE;
src = (__m128i*)d;
accumulator = _mm_loadu_si128(src);
output = 0;
for(i=BLOCKSIZE;i<len-remainder;i+=BLOCKSIZE){
xmm0 = _mm_loadu_si128(++src);
accumulator = _mm_add_epi32(accumulator,xmm0);
}
accumulator = _mm_add_epi32(accumulator, _mm_srli_si128(accumulator, 8));
accumulator = _mm_add_epi32(accumulator, _mm_srli_si128(accumulator, 4));
output = _mm_cvtsi128_si32(accumulator);
for(i=len-remainder;i<len;i++){
output += d[i];
}
return output;
}
Как вы можете видеть, это довольно прямо вперед, реализация которой я просуммировать массив 4 в то время, используя расширенные регистры XMM, а затем очистить в конце сложения остальных элементов.
Затем я сравнил производительность этой реализации SIMD с простым прохождением цикла. В результате этого эксперимента можно найти здесь:
Как вы можете видеть, по сравнению с для цикла, эта реализация действительно показывает около ~ 60% прирост скорости в течение входных размеров (то есть длина из массив) до примерно 5 М элементов. Однако при больших значениях входного размера производительность по отношению к циклу for берет резкое погружение и производит только около 20% ускорения.
Я затрудняюсь объяснить это резкое снижение производительности. Я более или менее чередуюсь линейно по памяти, поэтому влияние промахов кэша и ошибок страниц должно быть примерно одинаковым для обеих реализаций. Что мне здесь не хватает? Есть ли способ сгладить эту кривую? Любые мысли были бы весьма признательны.
Какой процессор вы используете? –
Во-первых, вы проверили, будет ли gcc autovectorizes скалярным кодом? Во-вторых, вы, вероятно, будете ограничены пропускной способностью. – EOF
Как @EOF говорит, вы почти ничего не делаете в своем цикле (одна арифметическая инструкция SIMD), поэтому вы, скорее всего, будете ограничены пропускной способностью памяти, если у вас большие массивы. –