Programmazione Funzionale e Parallela

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2017-2018

HomePage | Avvisi | Diario lezioni | Materiale didattico | Esami | Forum | Login

Revision [904]

Last edited on 2017-11-25 15:21:59 by CamilDemetrescu
Additions:
%%(c;decode.h)
#ifndef __DECODE__
#define __DECODE__
void decode(const char* key, int m, char* str);
%%(c;main.c)
#define STR "Tjit#lkbsdr{ jv hrfh uogwwcrf> {ov#ccn!uefitwrkbvwe\"iu#apd0rr\"mp" \
"gihy!lt\"uoget uke\"tfumu pi vhf#GPU!Oeusfu Ieohrcl!SudljfLkcfqsg " \
"bv rucoiuhfg dy!whg Gueg Trfvwbue\"Fpxnfaulop;!hivhfu xesviqn!5.3 " \
"pi vhf#Lkcfqsg,!rr\"(bw {ovu qpulop)!dn{ mdtgr!yetsjrn0"

// ---------------------------------------------------------------------
// decode_ok
// ---------------------------------------------------------------------
void decode_ok(const char* key, int m, char* str) {
for (i=0; i // ---------------------------------------------------------------------
// main
// ---------------------------------------------------------------------
int main(int argc, char* argv[]) {
const char k1[] = { 0, 2, 0, 1, 3 };
char s1[] = STR;
char o1[] = STR;
decode(k1, 5, s1);
decode_ok(k1, 5, o1);
printf("------- Calcolato: \n%s\n", s1);
printf("------- Corretto: \n%s\n", o1);
printf("------- Esito: %s\n", strcmp(s1,o1)==0 ? "OK":"ERRORE");
%%(text;Makefile)
CC=gcc
CFLAGS=-Wall -O1 -g
LFLAGS=-msse2
decode: decode.c decode.h main.c
$(CC) $(CFLAGS) decode.c main.c -o decode $(LFLAGS)
.phony: clean
clean:
rm -f decode


Revision [903]

Edited on 2017-11-25 15:19:17 by CamilDemetrescu
Additions:
==Esempio 4==
Soluzione con vettorizzazione SSE dell'esercizio 2 compito A del 14 gennaio 2016:
%%(c;decode.c)
#include "decode.h"
#include
void decode(const char* key, int m, char* str) {
int i, n = strlen(str);
char keybuf[16] = { 0 };
memcpy(keybuf, key, m);
__m128i k = _mm_loadu_si128((__m128i*)keybuf);
for (i=0; i+16 < n; i += m) {
__m128i s = _mm_loadu_si128((__m128i*)(str+i));
s = _mm_sub_epi8(s,k);
_mm_storeu_si128((__m128i*)(str+i), s);
for (; i


Revision [900]

Edited on 2017-11-25 15:10:04 by CamilDemetrescu
Additions:
==Esempio 3==


Revision [899]

Edited on 2017-11-25 15:09:17 by CamilDemetrescu
Additions:
Compilazione versioni con piccola memory footprint (array di 1000 elementi):
> gcc vecsum.c -D VERSION=1 -o vecsum-sse -O1
> gcc vecsum.c -D VERSION=0 -o vecsum -O1
> time ./vecsum
0 0 0 0 0
real 0m0.047s
user 0m0.046s
sys 0m0.000s
> time ./vecsum-sse
0 0 0 0 0
real 0m0.016s
user 0m0.013s
sys 0m0.000s
Compilazione versioni con alta memory footprint (array di 100000000 elementi):
> gcc vecsum.c -D VERSION=1 -D N=100000000 -D M=1 -o vecsum-large-sse -O1
> gcc vecsum.c -D VERSION=0 -D N=100000000 -D M=1 -o vecsum-large -O1
> time ./vecsum-large
0 0 0 0 0
real 0m0.095s
user 0m0.074s
sys 0m0.021s
> time ./vecsum-large-sse
0 0 0 0 0
real 0m0.073s
user 0m0.031s
sys 0m0.040s
Si noti come in questo secondo caso lo speedup sia nettamente inferiore. La motivazione è che gli array sono grandi e il collo di bottiglia è il sistema di memoria e non il calcolo delle operazioni aritmetiche.
Deletions:
Compilazione versioni:
> gcc


Revision [898]

Edited on 2017-11-25 15:00:48 by CamilDemetrescu
Additions:
sum_sse(A+i,B+i,C+i); // versione SSE
Deletions:
sum_sse(A+i,B+i,C+i); // versione SSE


Revision [897]

Edited on 2017-11-25 15:00:38 by CamilDemetrescu
Additions:
Somma di array di ##int## di dimensione arbitraria usando vettorizzazione SSE:
%%(c;vecsum.c)
void sum_sse(int A[4], int B[4], int C[4]);
void vecsum(int* A, int* B, int* C, int n) {
int i;
#if VERSION == 1
sum_sse(A+i,B+i,C+i); // versione SSE
#else
C[i]=A[i]+B[i]; // versione sequenziale, con loop unrolling
C[i+1]=A[i+1]+B[i+1];
C[i+2]=A[i+2]+B[i+2];
C[i+3]=A[i+3]+B[i+3];
#endif
for (;i void sum_sse(int A[4], int B[4], int C[4]) {
void init(int* v, int n) {
int i;
for (i=0; i #ifndef N
#define N 1000
#endif
#ifndef M
#define M 100000
#endif
// provare anche con M=1 e N=100000000:
// array A, B, C da 100 milioni di int => 1.2 GB per 3 array di int
// (collo di bottiglia memoria vanifica parallelismo)
int j;
int* A = malloc(N*sizeof(int));
int* B = malloc(N*sizeof(int));
int* C = malloc(N*sizeof(int));
// ripete per rendere misurabili i tempi
for (j=0; j printf("%d %d %d %d %d\n", C[0], C[1], C[2], C[3], C[4]);
Compilazione versioni:
> gcc


Revision [896]

Edited on 2017-11-25 14:50:47 by CamilDemetrescu
Additions:
===Giovedì 23 novembre 2017===
==Esempio 2==
Prodotto scalare di array di ##int## di dimensione arbitraria usando vettorizzazione SSE:
%%(c;scalprod.c)
void prod_sse(int A[4], int B[4], int C[4]);
int scalprod(int* A, int* B, int n) {
int i, s = 0, S[4] = { 0 }, P[4];
for (i=0; i+3 prod_sse(A+i,B+i,P);
somma_sse(P, S, S);
}
for (; i __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
void prod_sse(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_mullo_epi32(a,b); // calcola la somma vett. di a e b
_mm_store_si128((__m128i*)C, c); // copia risultato c in C
int B[] = { 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1 };
int s = scalprod(A, B, sizeof(A)/sizeof(int));


Revision [895]

Edited on 2017-11-25 14:49:03 by CamilDemetrescu
Additions:
==Esempio 1==
Somma degli elementi di un array di ##int## di dimensione arbitraria usando vettorizzazione SSE:


Revision [894]

Edited on 2017-11-25 14:48:04 by CamilDemetrescu
Additions:
__m128i a, b, c; // dich. variabili vettoriali
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
Deletions:
__m128i a, b, c; // dich. variabili vettoriali
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


Revision [893]

The oldest known version of this page was created on 2017-11-25 14:47:54 by CamilDemetrescu
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by WikkaWiki
Page was generated in 0.0302 seconds