Aunque evidentemente podríamos estar ejecutando un programa de forma paralela en un sistema con un solo procesador la auténtica ventaja de esta programación es hacer que varios procesadores puedan estar ejecutando simultáneamente distintas instrucciones de nuestro programa.
Hay varias arquitectura de sistemas con capacidad de proceso en paralelo:
- Varios procesadores que comparte la memoria central (y puede que compartan o no la caché).
- Procesadores que cada uno tiene su memoria pero comparten el resto de la arquitectura
- Clusters de ordenadores.
Sin expandirme más en estos conceptos ya que hay mucho escrito (y mucho discutido) sobre ello voy a explicar algunas técnicas de programación paralela en sistemas de memoria compartida.
Sistemas cuya arquitectura es similar a esta:
Fuente: wikipedia
OpenMP
OpenMP (Open Multi-Processing) es una interfaz para la programación multiproceso de memoria compartida en múltiples plataformas, entre ellas Unix y Windows y en la actualidad está disponible para los lenguajes C/C++ y Fortran.OpenMP está compuesto por
- Un conjunto de directivas de compilador
- Rutinas de biblioteca
- Variables de entorno
OpenMP basa el paralelismo en el uso threads cuyo número deberá coincidir con el número de procesadores. Se puede definir mas threads que procesadores pero el paralelismo real no mejora.
Directivas
El estar fuertemente basado en directivas nos indica que gran parte del trabajo para la creación del código de proceso paralelo es realizado por el compilador. Deberemos ver que nuestro compilador soporta OpenMP.Compilador | Version | OMP |
---|---|---|
Intel C/C++, Fortran | 12.1 | OpenMP 3.1 |
GNU C/C++, Fortran | 4.4.6 | OpenMP exer |
PGI C/C++, Fortran | 8.0.1 | OpenMP 3.0 |
IBM Blue Gene C/C++ | 12.1 | OpenMP 3.1 |
IBM Blue Gene Fortran | 14.1 | OpenMP 3.1 |
IBM Blue Gene GNU C/C++, Fortran | 4.4.6 | OpenMP 3.0 |
Los flags de compilación para cada compilador son:
Compilador / Platforma | Compilador | Flag |
---|---|---|
Intel Linux Opteron/Xeon |
icc icpc ifort |
-openmp |
PGI Linux Opteron/Xeon |
pgcc pgCC pgf77 pgf90 |
-mp |
GNU Linux Opteron/Xeon IBM Blue Gene |
gcc g++ g77 gfortran |
-fopenmp |
IBM Blue Gene |
bgxlc_r, bgcc_r bgxlC_r, bgxlc++_r bgxlc89_r bgxlc99_r bgxlf_r bgxlf90_r bgxlf95_r bgxlf2003_r*Be sure to use a thread-safe compiler - its name ends with _r |
-qsmp=omp |
Funciones de run-time
Entre las más usadas tenemos:- omp_set_num_threads()
- omp_get_num_threads()
- omp_get_thread_num()
Estas funciones las veremos en detalle en los ejemplos que iré desarrollando en artículos siguientes.
Un programa usando OpenMP tendría esta forma:
C / C++ - Estructura tipo |
#include <omp.h> main () { int var1, var2, var3; // Parte del código no parelelo ......................; ..................... ; ..................... ; ..................... ; // Inicio del código paralelo #pragma omp parallel private(var1, var2) shared(var3) { Código paralelo usado por todas las . ..................................; ..................................; ..................................; // Otras directivas de OpenMP // Llamadas a rutinas de run´-time } Continua el código no paralelo . . . } |
Requisitos.
Para poder seguir los siguientes artículos será bueno tener un ordenador con al menos dos procesadores y ejecutar un programa que sea intensivo en cálculo.Este programa que sirve para calcular el número Pi será la herramienta de trabajo para ir viendo las técnicas de programación paralela.
#include <stdio.h> #include <omp.h> static long num_steps = 100000000; double step; int main() { int i; double x, pi, sum =0.0; step = 1.0/(double) num_steps; for (i = 0; i < num_steps; i++) { x = (i + 0.5) * step; sum = sum + 4.0/(1.0 +x*x); } pi = step * sum; printf("El numero Pi es: %2.10f\n", pi); } |
Dependiendo de la potencia de nuestros procesadores deberemos hacer mayor o menor el valor de la variable num_steps.
Seguimos en el siguiente post......