2011-10-05 17 views
6

¿Por qué el compilador de intel no me permite especificar que algunas acciones en un bloque openmp parallel for solo deben ejecutarse mediante el hilo maestro?el pragma "maestro" de OpenMP no debe estar encerrado en el pragma "paralelo para"

¿Y cómo puedo hacer lo que intento sin este tipo de funcionalidad?

Lo que estoy tratando de hacer es actualizar una barra de progreso a través de una devolución de llamada en un paralelo para:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    #pragma omp master 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 

quiero solamente el hilo principal para llamar a la devolución de llamada, porque si no lo imponen (por ejemplo mediante el uso de omp critical vez que exista un sólo hilo utiliza la devolución de llamada a la vez) me sale el siguiente excepción de ejecución:

The application called an interface that was marshalled for a different thread. 

... de ahí el deseo de mantener todas las devoluciones de llamada en el hilo principal.

Gracias de antemano.

Respuesta

6
#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
     f(); 
    } 
    return 0; 
} 

Error del compilador C3034 OpenMP Directiva 'maestro' no puede estar anidada directamente en 'paralelo para' directiva Visual Studio 2010 OpenMP 2.0

puede ser así:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    //#pragma omp master it is error 
    //#pragma omp critical it is right 
    if (omp_get_thread_num() == 0) // may be good 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 
+0

Esto parece estar funcionando, gracias. Me preocupaba que el hilo maestro pudiera ser diferente a todos los hilos de trabajo ... para que la devolución de llamada nunca se ejecutara ... ¿es eso concebible dentro de la especificación omp? –

+0

Si el número de iteraciones es grande, entonces no notará la diferencia. Y después del bucle agrega: if (omp_get_thread_num() == 0) set_progressor_callback (num_items_computed); –

+0

desde el estándar OpenMP sobre pragma omp parallel for(): "La construcción de bucle especifica que las iteraciones de uno o más bucles asociados se ejecutarán en paralelo por hilos en el equipo en el contexto de sus tareas implícitas.Las iteraciones se distribuyen a través de subprocesos que ya existen en el equipo que ejecuta la región paralela a la que se vincula la región de bucle. " –

3

La razón por la cual obtiene el error es porque el hilo maestro no está allí la mayoría de las veces cuando el código llega a la línea #pragma omp master. Por ejemplo, tomemos el código de Artyom:

#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
      f(); 
    } 
    return 0; 
} 

Si el código se compilará, podría pasar lo siguiente:

Digamos hilo 0 aperturas (el hilo principal). Alcanza el pragma que prácticamente dice "Maestro, haz la siguiente pieza de código". Siendo el maestro puede ejecutar la función. Sin embargo, ¿qué sucede cuando el subproceso 1 o 2 o 3, etc. alcanza ese fragmento de código?

La directiva maestra indica al equipo presente/escucha que el hilo maestro tiene que ejecutar f(). Pero el equipo es un hilo único y no hay un maestro presente. El programa no sabría qué hacer después de ese punto.

Y es por eso que, creo, el maestro no puede estar dentro del for-loop.

Sustituyendo el master directive con if (omp_get_thread_num() == 0) funciona porque ahora el programa dice: "Si eres maestro, haz esto. De lo contrario, ignora".

Cuestiones relacionadas