tutorial punto producto paralelo paralelizar hilos español ejemplos calculo c++ arrays openmp reduction

c++ - punto - ¿Es posible hacer una reducción en una matriz con openmp?



paralelizar en c (5)

¿OpenMP soporta nativamente la reducción de una variable que representa una matriz?

Esto funcionaría algo como lo siguiente ...

float* a = (float*) calloc(4*sizeof(float)); omp_set_num_threads(13); #pragma omp parallel reduction(+:a) for(i=0;i<4;i++){ a[i] += 1; // Thread-local copy of a incremented by something interesting } // a now contains [13 13 13 13]

Idealmente, habría algo similar para un omp paralelo, y si tiene un número suficientemente grande de hilos para que tenga sentido, la acumulación se producirá a través de un árbol binario.



La reducción de matrices ahora es posible con OpenMP 4.5 para C y C ++. Aquí hay un ejemplo:

#include <iostream> int main() { int myArray[6] = {}; #pragma omp parallel for reduction(+:myArray[:6]) for (int i=0; i<50; ++i) { double a = 2.0; // Or something non-trivial justifying the parallelism... for (int n = 0; n<6; ++n) { myArray[n] += a; } } // Print the array elements to see them summed for (int n = 0; n<6; ++n) { std::cout << myArray[n] << " " << std::endl; } }

Salidas:

100 100 100 100 100 100

Compilé esto con GCC 6.2. Puede ver qué versiones comunes de compiladores admiten las características de OpenMP 4.5 aquí: http://www.openmp.org/resources/openmp-compilers/

Note en los comentarios anteriores que, si bien esta es una sintaxis conveniente, puede invocar muchos gastos generales al crear copias de cada sección de matriz para cada subproceso.


OpenMP no puede realizar reducciones en las variables de tipo de matriz o estructura (ver restrictions ).

También es posible que desee leer sobre cláusulas private y shared . private declara que una variable es privada para cada subproceso, mientras que como shared declara que una variable se comparte entre todos los subprocesos. También encontré la respuesta a esta question muy útil con respecto a OpenMP y matrices.


OpenMP puede realizar esta operación a partir de OpenMP 4.5 y GCC 6.3 (y posiblemente inferior) lo admite. Un programa de ejemplo se ve como sigue:

#include <vector> #include <iostream> int main(){ std::vector<int> vec; #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) #pragma omp parallel for default(none) schedule(static) reduction(merge: vec) for(int i=0;i<100;i++) vec.push_back(i); for(const auto x: vec) std::cout<<x<<"/n"; return 0; }

Tenga en cuenta que omp_out y omp_in son variables especiales y que el tipo de declare reduction debe coincidir con el vector que está planeando reducir.