miércoles, 25 de febrero de 2015

Programación paralela (I)

La programación paralela es una forma de programar que permite que partes de un programa se ejecuten simultáneamente en dos o más CPU's.
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. 
Cada tipo de arquitectura requiere que unsoftware  que sea capaz gestionar cada una.
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

  1. Un conjunto de directivas de compilador 
  2. Rutinas de biblioteca 
  3. 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++, Fortran12.1OpenMP 3.1
GNU C/C++, Fortran4.4.6OpenMP exer
PGI C/C++, Fortran8.0.1OpenMP 3.0
IBM Blue Gene C/C++12.1OpenMP 3.1
IBM Blue Gene Fortran14.1OpenMP 3.1
IBM Blue Gene GNU C/C++, Fortran4.4.6OpenMP 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......

No hay comentarios:

Publicar un comentario