¿Cómo son las cláusulas privateprivadas y lastprivate diferentes de privadas en OpenMP?

Miré las definiciones oficiales, pero todavía estoy bastante confundido.

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

Para mí, eso suena muy privado. He buscado ejemplos, pero no entiendo cómo es especial o cómo se puede usar.

lastprivate : especifica que la versión de la variable del contexto que lo incluye se establece igual a la versión privada del hilo que ejecuta la iteración final (constructo for-loop) o la última sección (secciones #pragma).

Siento que entiendo esto un poco mejor por el 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 se i devuelva fuera del ciclo como el último valor que era.

Empecé a aprender OpenMP hoy.

private variables private no se inicializan, es decir, comienzan con valores aleatorios como cualquier otra variable automática local (y a menudo se implementan usando variables automáticas en la stack de cada hilo). Tome este progtwig simple como un ejemplo:

 #include  #include  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 produce algo así 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 inicializado) dentro de la región paralela y que las modificaciones no son visibles después de la región paralela (es decir, la variable mantiene su valor antes de ingresar a la región).

Si i hacen firstprivate , entonces 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 

Todavía las modificaciones al valor de i dentro de la región paralela no son visibles después de esto.

Ya sabe sobre lastprivate (y no es aplicable al progtwig de demostración simple ya que carece de construcciones de trabajo compartido).

Entonces 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. El razonamiento detrás de estas clases de intercambio de datos es que dentro de la región paralela todas las variables privadas sombrean las del contexto externo, es decir, no es posible usar una operación de asignación para modificar el valor exterior de i desde el interior de la región paralela.

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.