Mercoledì 22 novembre 2017
Esempio 1
Somma vettoriale di array a 128 bit:
#include <immintrin.h>
#include <stdio.h>
void somma
(int A
[4],
int B
[4],
int C
[4]) {
__m128i a, b, c;
// dich. variabili vettoriali
a = _mm_loadu_si128
((const __m128i*
)A
);
// copia primo vettore in a
b = _mm_loadu_si128
((const __m128i*
)B
);
// copia secondo vettore in b
c = _mm_add_epi32
(a,b
);
// calcola la somma vett. di a e b
_mm_store_si128
((__m128i*
)C, c
);
// copia risultato c in C
}
int main
() {
int A
[4] =
{ 1,
2,
3,
4 };
int B
[4] =
{ 4,
3,
2,
1 };
int C
[4];
somma
(A,B,C
);
printf("%d %d %d %d\n", C
[0], C
[1], C
[2], C
[3]);
// stampa 5 5 5 5
return 0;
}
Compilazione:
> gcc sum128.c -o sum128 -O1 -msse2
Perché
sse2? Si consulti la
guida Intel intrinsic SIMD e si noti che le istruzioni
_mm_loadu_si128,
_mm_storeu_si128 e
_mm_add_epi32 sono disponibile a partire dalla tecnologia
SSE 2.
Esempio 2
Somma vettoriale di array a 256 bit:
#include <immintrin.h>
#include <stdio.h>
void somma
(int A
[8],
int B
[8],
int C
[8]) {
__m256i a, b, c;
// dich. variabili vettoriali
a = _mm256_load_si256
((const __m256i*
)A
);
// copia primo vettore in a
b = _mm256_load_si256
((const __m256i*
)B
);
// copia secondo vettore in b
c = _mm256_add_epi32
(a,b
);
// calcola la somma vett. di a e b
_mm256_store_si256
((__m256i*
)C, c
);
// copia risultato c in C
}
int main
() {
int A
[8] __attribute__
((aligned
(32))) =
{ 1,
2,
3,
4,
2,
3,
4,
5 };
int B
[8] __attribute__
((aligned
(32))) =
{ 4,
3,
2,
1,
4,
3,
2,
1 };
int C
[8] __attribute__
((aligned
(32)));
somma
(A,B,C
);
printf("%d %d %d %d %d %d %d %d\n", C
[0], C
[1], C
[2], C
[3], C
[4], C
[5], C
[6], C
[7]);
// stampa 5 5 5 5 6 6 6 6
return 0;
}
Compilazione:
> gcc sum256.c -o sum256 -O1 -mavx2
Codice assembly 64 bit per la funzione
somma:
somma:
vmovdqa (%rdi), %ymm0
vpaddd (%rsi), %ymm0, %ymm0
vmovdqa %ymm0, (%rdx)
ret