La creación de herbas por parte de OpenMP lleva un coste que para algunos cálculos no es eficiente paralelizar.
Para comparar el coste vamos a realizar el siguiente ejercicio. Tenemos un algoritmo secuencial y se quiere hacer de forma paralela. Ten en cuenta que el algoritmo tiene calcula datos dependiendo de otros, los cuales imposibilitan que la paralelización sea inmediata.
A continuación tenemos un código de ejemplo.
#include <omp.h> #include <iostream> #include <vector> using namespace std; int main (){ unsigned int N; cout<<"introduce el tamaño del vector"<<endl; cin>>N; double timeIni, timeFin; vector<int> x(N), y(N); timeIni = omp_get_wtime(); //Secuencial for(int i=1; i < N ; i++){ x[i] = y[i-1] * 2; y[i] = y[i] + i; } timeFin = omp_get_wtime(); cout<<"Tiempo tardado secuencial = "<< (timeFin - timeIni)*1000 <<" milisegundos"<<endl; timeIni = omp_get_wtime(); //Paralelo //Escriba el mismo algoritmo de forma paralela timeFin = omp_get_wtime(); cout<<"Tiempo tardado paralelo = "<< (timeFin - timeIni)*1000 <<" milisegundos"<<endl; }
La dependencia de datos se ha resulto invirtiendo el orden de calculo.
#pragma omp parallel for for(int i=0; i < N ; i++){ y[i] = y[i] + i; x[i+1] = y[i] * 2; }
A continuación se muestran los resultados obtenidos de la ejecución del programa en un equipo con dos núcleos.
Para comprobar el numero de hebras que se ejecutan se separa la directiva #pragma omp parallel for en dos, #pragma omp parallel y #pragma omp for.
Las hebras creadas en la primera directiva son las usadas en el for, repartiendo las iteraciones como indique la segunda directiva. Para mostrar un mensaje no repetido con el numero de hebras ejecutadas se usara la directiva #pragma omp single, cuyo código solo sera ejecutado por una de las hebras.
#pragma omp parallel if( N > 10000 ) { #pragma omp single cout<<"Numero de hebras = "<<omp_get_num_threads()<<endl; #pragma omp for for(int i=0; i < N ; i++){ y[i] = y[i] + i; x[i+1] = y[i] * 2; } }