ud3 inocente alcaide

21
UD3 - OpenMP Programación de Memoria Compartida ARQUITECTURA DE COMPUTADORES

Upload: inocente-alcaide

Post on 04-Aug-2015

54 views

Category:

Engineering


1 download

TRANSCRIPT

UD3 - OpenMPProgramación de Memoria Compartida

ARQUITECTURA DE COMPUTADORES

1. Qué es OpenMP. Compiladores y lenguajes que lo admiten

OpenMP es una interfaz de programación de aplicaciones (API) para laprogramación paralela de memoria compartida multiplataforma. “MP” son lassiglas de multiprocesamiento. OpenMP está diseñado para sistemas en las quecada hilo o proceso pueden, potencialmente, tener acceso a toda la memoriadisponible. Cuando se programa con OpenMP, consideramos nuestro sistema comouna colección de núcleos o CPUs (que procesan los hilos), y en que todos tienenacceso a la memoria principal.

1. Qué es OpenMP. Compiladores y lenguajes que lo admiten

2. Como configurar un entorno de desarrollo en OpenMP y C++

El ambiente de desarrollo Code::BlocksCode::Blocks es un entorno de desarrollo integrado libre y multiplataforma para el desarrollo de programas en lenguaje C y C++ disponible para Microsoft Windows, Apple OSX y Linux. Está basado en la plataforma de interfaces gr aficas WxWidgets, por lo que se ha portado a diversos sistemas operativos, y está licenciado bajo la licencia pública general de GNU. Sus distintas versiones junto a la documentaci on correspondiente est an disponibles en http://www.codeblocks.org. Code::Blocks puede enlazarse a una variedad de compiladores, como el Microsoft Visual Studio Toolkit, el compilador C++ de Intel y, en particular, el compilador MinGW. Este ultimo es una implementación de los compiladoresGCC para la plataforma Win32, lo que permite hacer uso de sus conocidas capacidades en ambientes Windows.

2. Como configurar un entorno de desarrollo en OpenMP y C++

Instalación del compilador Code::BlocksLa versión 12.11 del ambiente de desarrollo Code::Blocks est a disponible para Microsoft Windows en http://www.codeblocks.org/downloads/26. En esta p agina hay dos versiones: codeblocks-12.11-setup.exe y codeblocks-12.11mingw-setup.exe. Es necesario bajar esta ultima versióon, pues solo ésta contiene la versión 4.7.1 de 32 bits del compilador GCC y del depurador GDB de Twilight Dragon Media (MinGW TDM-GCC).

Una vez obtenido el archivo de instalación, éste se ejecuta, lo que instala el compilador en la ruta de acceso por omisión, c:\Programiles\CodeBlocks. Es posible instalar el compilador en otro directorio, si así se quisiera.

2. Como configurar un entorno de desarrollo en OpenMP y C++

Instalación de la biblioteca OpenMPPara utilizar la biblioteca OpenMP con Code::Blocks, es necesario además instalar el paquete OpenMP para TDM-GCC, gcc-4.7.1-tdm-1-openmp.zip, el cual puede obtenerse de http://tdm-gcc.tdragon.net/download. Este paquete debe instalarse en el directorio raíz de instalación del compilador MinGW, c:\Program Files\CodeBlocks\MinGW

2. Como configurar un entorno de desarrollo en OpenMP y C++

Definición de las opciones del proyectoUna vez creado un proyecto en el ambiente de desarrollo Code::Blocks, se deben definir las opciones del proyecto de manera de utilizar la biblioteca OpenMP. Para ello, acceda a la opción Build Options... del menú Project . Allí, en la pestaña Compiler Settings, agregue la opción -fopenmp bajo la pestaña Otheroptions. Luego, en la pestaña Linker Settings, en la ventana other linker optionsagregue también la opción -fopenmp

2. Como configurar un entorno de desarrollo en OpenMP y C++

Verificando la instalaciónFinalmente, verifique su instalación compilando y ejecutando exitosamente el siguiente programa en OpenMP. Su salida debe indicar la versión de OpenMPen uso, el número de procesadores disponibles y muestra además cómo crear hebras usando el pragma parallel.

2. Como configurar un entorno de desarrollo en OpenMP y C++

Verificando la instalación#include <omp.h>

#include <stdio.h>

#include <stdlib.h>

int main()

{

int n_hebras, h_id, n_procs;

printf("Esto es OpenMP, version %d\n", _OPENMP);

// Numero de procesadores

n_procs = omp_get_num_procs();

2. Como configurar un entorno de desarrollo en OpenMP y C++

Verificando la instalaciónprintf("Numero de procesadores: %d\n", n_procs);

// Creacion de hebras

omp_set_num_threads(n_procs);

#pragma omp parallel

printf("Soy la hebra %d de %d\n", omp_get_thread_num(),

omp_get_num_threads());

return 0;

}

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

OpenMP comienza a través de directivas, con funciones propias (que pueden ser condicionalmente compiladas) y variables de entorno, que pueden modificar el comportamiento en tiempo de ejecución.

1. Directiva de formato. Cada directiva inicia con #pragma omp ...#pragma omp directive-name[clause[,] clause]...

2. Constructor paralelo. Las siguientes directivas definen una región paralela, la cual es una parte del programa que puede ser ejecutada por múltiples threadsen paralelo. Este es el constructor fundamental que inicia la ejecución paralela.

#pragma omp parallel [clause[,] clause]...

{

bloque de código

}

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

La cláusula puede ser: • if(expresión escalar)

• private(lista de variables)

• firstprivate(lista de variables)

• default(shared | none)

• shared(lista de variables)

• copyin(lista de variables)

• reduction(operador:lista de variables)

• num_threads(expresión entera)

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

Entre las cláusulas que se pueden utilizar, las más usadas son: • private(lista de variables) En esta la lista de variables puede ser separada por "," y para

cada una de ellas se genera una copia en cada thread, esta copia no tiene relación con la original y no es inicializada a menos que se utilice firstprivate.

• shared(lista de variables) En esta las variables de la lista son comunes a todos los threadsy cada uno de ellos puede modificarla afectándola en forma global.

• threadprivate(lista de variables) Hace que la lista sea privada a cada thread pero globales dentro de un thread.

• reduction(operador:lista de variables) Realiza una operación de reducción sobre las variables que aparecen en la lista utilizando el operador/intrínseco especificado. El operador puede ser: +, *, -, &(and), |(or), ^(eqv), &&(neqv). El intrínseco puede ser: || (max), (min), (and), (or).

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

Al final de una región paralela hay una sincronización implícita. Solo el thread master continúa la ejecución. Cuando un thread encuentra un constructor paralelo, un grupo de threads es creado si uno de los siguientes casos es verdadero:

• No está la cláusula if presente.

• Si al evaluar la expresión de if tiene un valor diferente de cero.

• Este thread se convierte en el thread maestro de un grupo, con el número de thread0, y todos los threads, incluyendo el maestro ejecutan la región paralela. Si el valor de la expresión if se hace cero la región es serializada nuevamente. Para determinar el número de threads necesarios, las siguientes reglas deben ser consideradas en orden. La primera regla que cumple la condición es aplicada:

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

1. Si la cláusula num_threads está presente, entonces la expresión entera en la cláusula es el número de threads requerido.

2. Si la función omp_set_num_threads de la librería es llamada, entonces el valor del argumento es el número de threads requeridos.

3. Si la variable de entorno OMP_NUM_THREADS es definida entonces el valor de esta variable de entorno es el número de threads requeridos.

4. Si ninguno de los métodos anteriormente mencionados es usado, entonces el número de threads requeridos en el definido por defecto.

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

3. Constructor for La directiva for identifica un constructor de trabajo compartido el cual especifica que las iteraciones del ciclo asociado deben ser ejecutadas en paralelo.

#pragma omp for[clause[,] clause]...

{

ciclo for

}

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

Las cláusulas que se pueden utilizar son las siguientes:

• private(lista de variables)

• firstprivate(lista de variables)

• lastprivate(lista de variables)

• reduction(operador:lista de variables)

• ordered

• schedule(categoría, tamaño_tramo)

• nowait

La cláusula lastprivate hace que la lista se comporte como si hubiese sido declarada privada, pero el último thread que ejecuta la sentencia de distribución de trabajo, actualiza con su valor privado (de la lista) el que hubiera antes del constructor.

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

La cláusula ordered es una instancia donde una parte de un ciclo puede ser ejecutada en orden serial, cuando el resto del ciclo se ejecuta en paralelo.

La cláusula schedule especifica cuántas iteraciones del for son divididas entre el número de threads, el valor de tamaño_tramo es especificado en el for, es invariante y es un número positivo. Las categorías utilizadas en esta cláusula puede ser una de las siguientes:

• static: cuando ésta es usada, el número de iteraciones es dividido en tramos de tamaño "tamaño_tramo" y es asignado en forma de "Round Robin".

• dynamic: cuando se usa esta categoría, la cantidad de iteraciones es dividida en una serie de tramos, cada una contiene "tamaño_tramo" iteraciones. Cada thread ejecuta su tramo y espera por más trabajo asignado.

• guided: para esta categoría las iteraciones son asignadas a los threads en tramos con tamaño decreciente. Cuando un thread finaliza el tramo de iteraciones asignado, a este se le asigna otro tramo dinámicamente hasta que se termine la repartición.

• runtime: cuando se usa runtime, las categorías de schedule son obtenidas en tiempo de ejecución con la configuración dada en la variable de entorno OMP_SCHEDULE.

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

Finalmente la cláusula nowait evita que haya una sincronización entre threads al final de la directiva de distribución de trabajo.

Ejemplo

#include <omp.h>

#include <stdio.h>

#include <stdlib.h>

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

int main(int argc, char **argv)

{

int pid;

#pragma omp parallel private( pid )

{

pid = omp_get_thread_num(); // entrega el nro de threadprintf("Soy el thread=%d\n",pid);

}

return 0;

}

3. Descripción general de las directivas de OpenMP a partir de un código de ejemplo

1. Indicar la cantidad de threads, a través de variables de entorno: setenv OMP_NUM_THREADS 4

2. Compilar la aplicación en un procesador intelicpc -o salida.exe prueba_1.cc –openmp

3. Ejecución de la aplicación.>./salida.exe

antes del pragma ...

Soy el thread=0

Soy el thread=3

Soy el thread=2

Soy el thread=1