¿OpenMP copia objetos privados?

Estoy escribiendo un programa que lee un archivo enorme (3x280 GB) y realiza un procedimiento de ajuste a los datos del archivo. Es bastante conveniente paralelizar un programa de este tipo, donde esto se hace fácilmente con OpenMP.

Lo que no entiendo es cómo se toman las variables privadas en OpenMP. Como todos sabemos, los objetos de fstream no se pueden copiar e, intuitivamente, eso me impidió usarlo como un objeto privado. Entonces el lector del archivo fue compartido.

Tuve un problema más tarde, y pensé en intentar tener fstreams como privados, ... ¿y adivina qué? ¡¡¡funcionó!!! ¡¿Cómo puede ser esto posible?! si el objeto no es copiable, ¿cómo podría OpenMP usar diferentes copias del mismo objeto para cada kernel?

Así es como se ve mi programa:

fstream dataReaderX(Dirs[0].c_str(), ios::in | ios::binary);
fstream dataReaderY(Dirs[1].c_str(), ios::in | ios::binary);
fstream dataReaderZ(Dirs[2].c_str(), ios::in | ios::binary);
#pragma omp parallel num_threads(cpus_num) shared(...) private(...,dataReaderX,dataReaderY,dataReaderZ)
{
...
}

Gracias por su atención.

preguntado el 12 de junio de 12 a las 16:06

1 Respuestas

firstprivate las variables se copian, no private - para este último, el constructor predeterminado se llama:

Sección 2.9.3.3 - private cláusula:

El nuevo elemento de la lista se inicializa o tiene un valor inicial indefinido, como si se hubiera declarado localmente sin un inicializador. No se especifica el orden en que se llama a los constructores predeterminados para diferentes variables privadas de tipo de clase. No se especifica el orden en que se llama a los destructores de C/C++ para diferentes variables privadas de tipo de clase.

Aquí hay un código de demostración simple:

#include <fstream>
#include <stdio.h>
#include <omp.h>

int main (void)
{
   std::fstream reader("test.txt", std::ios::in);
   printf("Main thread: reader.is_open() = %d\n", reader.is_open());
   #pragma omp parallel private(reader)
   {
      printf("Thread %d: reader.is_open() = %d\n",
             omp_get_thread_num(), reader.is_open());
   }
   return 0;
}

Y aquí está el resultado como se esperaba:

Main thread: reader.is_open() = 1
Thread 1: reader.is_open() = 0
Thread 0: reader.is_open() = 0
Thread 3: reader.is_open() = 0
Thread 2: reader.is_open() = 0

Una cosa divertida es que Intel C++ Compiler falla con un error interno (una afirmación fallida), probado con las versiones 11.1, 12.0 y 12.1. Por otro lado, el compilador GNU C++ se adhiere al estándar (el resultado anterior es de g++). Ambos compiladores se quejan cuando firstprivate en su lugar, aunque Intel C++ Compiler vuelve a tener un error interno.

Puede sonar estúpido, pero ¿comprobó que ha habilitado la compatibilidad con OpenMP en el compilador particular que está utilizando?

Respondido el 12 de junio de 12 a las 19:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.