introduccion example openmp

example - openmp ubuntu



¿En qué se diferencian de firstprivate y lastprivate las cláusulas privadas en OpenMP? (2)

He mirado las definiciones oficiales, pero todavía estoy bastante confundido.

firstprivate : especifica que cada subproceso debe tener su propia instancia de una variable y que la variable debe inicializarse con el valor de la variable, ya que existe antes de la construcción paralela.

Para mí, eso suena mucho como privado. Busqué ejemplos, pero no entiendo cómo es especial o cómo se puede usar.

lastprivate : Especifica que la versión de contexto de la variable se establece igual a la versión privada de cualquier subproceso que ejecute la iteración final (construcción de bucle for) o la última sección (secciones #pragma).

Siento que entiendo esto un poco mejor debido al siguiente ejemplo:

#pragma omp parallel { #pragma omp for lastprivate(i) for (i=0; i<n-1; i++) a[i] = b[i] + b[i+1]; } a[i]=b[i];

Entonces, en este ejemplo, entiendo que lastprivate permite que i sea ​​devuelto fuera del bucle como el último valor que tenía.

Acabo de empezar a aprender OpenMP hoy.


firstprivate y lastprivate son solo casos especiales de private .

El primero da como resultado la incorporación de valores del contexto externo a la región paralela, mientras que el segundo transfiere valores de la región paralela al contexto externo.


private variables private no se inicializan, es decir, comienzan con valores aleatorios como cualquier otra variable automática local (y a menudo se implementan utilizando variables automáticas en la pila de cada subproceso). Tomemos este sencillo programa como ejemplo:

#include <stdio.h> #include <omp.h> int main (void) { int i = 10; #pragma omp parallel private(i) { printf("thread %d: i = %d/n", omp_get_thread_num(), i); i = 1000 + omp_get_thread_num(); } printf("i = %d/n", i); return 0; }

Con cuatro hilos da como resultado algo como:

thread 0: i = 0 thread 3: i = 32717 thread 1: i = 32717 thread 2: i = 1 i = 10 (another run of the same program) thread 2: i = 1 thread 1: i = 1 thread 0: i = 0 thread 3: i = 32657 i = 10

Esto demuestra claramente que el valor de i es aleatorio (no está inicializado) dentro de la región paralela y que cualquier modificación no es visible después de la región paralela (es decir, la variable mantiene su valor antes de ingresar a la región).

Si i se convierte en firstprivate , se inicializa con el valor que tiene antes de la región paralela:

thread 2: i = 10 thread 0: i = 10 thread 3: i = 10 thread 1: i = 10 i = 10

Las modificaciones del valor de i dentro de la región paralela no son visibles después de esto.

Usted ya sabe acerca de lastprivate (y no es aplicable al programa de demostración simple, ya que carece de construcciones de trabajo compartido).

Así que sí, firstprivate y lastprivate son solo casos especiales de private . El primero da como resultado la incorporación de valores del contexto externo a la región paralela, mientras que el segundo transfiere valores de la región paralela al contexto externo. La razón detrás de estas clases de intercambio de datos es que dentro de la región paralela todas las variables privadas ocultan las del contexto externo, es decir, no es posible usar una operación de asignación para modificar el valor externo de i desde dentro de la región paralela.