SIMD-способный код?

Какое строгое определение того, какой код может использовать набор инструкций SIMD? Что-нибудь, где вы можете выполнять вычисления параллельно?

Так что, если бы я имел:

for(int i=0; i<100; i++){
sum += array[i];
}

это может использовать SIMD, потому что мы можем запустить:

for(int i=0; i<100;i=i+4){
sum0 += array[i];
sum1 += array[i+1];
sum2 += array[i+2];
sum3 += array[i+3];
}

sum = sum0 + sum1 + sum2 + sum3;

?

Это должны быть типы с плавающей запятой, или они могут быть двойными и целыми?

1

Решение

Предполагая, что вы говорите о x86 (SSE и другие) затем поддерживаются арифметические типы: целые числа 8, 16, 32 и 64 бита, а также числа с плавающей запятой одинарной и двойной точности. Однако обратите внимание, что не все арифметические операции поддерживаются для всех типов данных — SSE в этом отношении не хватает ортогональности.

Предполагая, что 32-битные целочисленные значения и соответственно выровненные массивы (выровнены по 16 байтам), вы можете реализовать приведенный выше пример цикла следующим образом:

#include <emmintrin.h>                     // SSE2 intrinsics

int32_t a[100] __attribute__ ((aligned(16)));
// suitably aligned array

__m128i vsum = _mm_set1_epi32(0);          // init vsum = { 0, 0, 0, 0 }
for (int i = 0; i < 100; i += 4)
{
__m128i v = _mm_load_si128(&a[i]);     // load 4 ints from a[i]..a[i+3]
vsum = _mm_add_epi32(vsum, v);         // accumulate 4 partial sums
}
// final horizontal sum of partial sums
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8));
int32_t sum = _mm_cvtsi128_si32(vsum);     // sum = scalar sum of a[]
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]