es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

OpenMP: ¿No es posible utilizar omp parallel for y omp task juntos? / error: la región de compartición de trabajo no puede estar anidada estrechamente dentro de otra región de compartición de trabajo.

En mi implementación en c++, tengo una función recursiva y llamo a esta función recursiva dentro de un bucle. Quiero usar OpenMP para crear paralelismo.

funcion llamadora(){

  #pragma omp parallel    
  {  
    #pragma omp for nowait    
    for (int i = 0; i < num; i++){
        #pragma omp single
        funcion_recursiva(n);   
    }
  }
}

void funcion_recursiva(n){

  if (x){
    #pragma omp task
    funcion_recursiva(n-1);   
  }   
  else{
    #pragma omp task
    funcion_recursiva(n-2);  
  }
}

Básicamente, quiero que el bucle externo sea ejecutado por varios hilos, pero luego, cuando se trata de la función recursiva, solo un hilo debería comenzar a ejecutarla y luego las llamadas recursivas deberían ser manejadas con nuevas tareas (que vendrán con “omp pragma task”).

Sin embargo, recibo este error de compilación:

error: la región de compartir el trabajo no puede estar anidada estrechamente dentro de una región de compartir trabajo, ‘critical’, ‘ordered’, ‘master’, ‘explicit task’ o la región ‘taskloop’
68 | #pragma omp single

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El error de compilación sugiere que la directiva #pragma omp single no puede estar anidada dentro de una directiva #pragma omp for. Esto se debe a que la directiva #pragma omp single se utiliza para asegurarse de que una región específica de código sea ejecutada por solo un hilo, mientras que la directiva #pragma omp for se utiliza para paralelizar un bucle en múltiples hilos.

    Para solucionar el problema, la directiva #pragma omp single debe ser movida fuera de la directiva #pragma omp for, de la siguiente manera:

    funcion llamadora(){
    
        #pragma omp parallel    
        {  
            #pragma omp single
            {
                #pragma omp for nowait    
                for (int i = 0; i < num; i++){
                    funcion_recursiva(n);   
                }
            }
        }
    }
    
    void funcion_recursiva(n){
    
        if (x){
            #pragma omp task
            funcion_recursiva(n-1);   
        }   
        else{
            #pragma omp task
            funcion_recursiva(n-2);  
        }
    }
    

    Aquí, la directiva #pragma omp single se aplica solo una vez al bucle, antes de que comience el bucle. Una vez que el bucle comienza, múltiples hilos pueden ejecutarlo en paralelo. Las directivas #pragma omp task se utilizan para paralelizar las llamadas recursivas dentro de cada iteración del bucle.

Comments are closed.