martes, 12 de agosto de 2008

Operaciones vectoriales en C++

Una de las mejoras que tienen los nuevos procesadores sobre los antiguos es la inclusión de operaciones vectoriales o SIMD (Single Instruction Multiple Data).

Estas instrucciones básicamente operan bajo un conjunto de datos (normalmente un vector) en paralelo reduciendo brutalmente el tiempo de ejecución.

En la web de gcc sobre operaciones vectoriales se explica como se pueden usar.

Para compilarlo con gcc se pueden pasar las opciones -mmmx, -msse, -msse2, -msse3 o -m3dnow, según el procesador será mejor una u otra.

En el siguiente ejemplo se consigue una mejora de entre 5 o 6 veces usando las instrucciones SIMD en mi Pentium IV.

#include <iostream>

#define SIZE 8

using namespace std;

typedef int vectorSIMD __attribute__ ((vector_size(SIZE*4)));

int main() {
long int start, end, tiempo1, tiempo2;
int repeticiones = 9999999;

int total[] = {0, 0, 0, 0, 0, 0, 0, 0};
int sumando[] = {1, 4, 3, 7, 2, 4, 5, 6};

vectorSIMD totalV = {0, 0, 0, 0, 0, 0, 0, 0};
vectorSIMD sumandoV = {1, 4, 3, 7, 2, 4, 5, 6};

cout << "Empezando suma de vectores" << endl;
start=clock();
for (int i=0;i<repeticiones;i++){
for(int j=0;j<SIZE;j++){
total[j]+=sumando[j];
}
}
end=clock();
tiempo1=end-start;
cout << "Suma de vectores realizada en " << tiempo1 << " tics de reloj" << endl;

cout << "Empezando suma vectorial" << endl;
start=clock();
for (int i=0;i<repeticiones;i++){
totalV+=sumandoV;
}
end=clock();
tiempo2=end-start;
cout << "Suma vectorial realizada en " << tiempo2 << " tics de reloj" << endl;

cout << "Se ejecuta " << tiempo1/((float)tiempo2) << " veces mas rapido con las instrucciones SIMD" << endl;
}

0 comentarios: