2012-08-17 29 views
16

Tengo un problema con la compilación de OpenMP.Cómo compilar openmp usando g ++

Al igual que el siguiente código:

#include <iostream> 
#include <pthread.h> 
#include <omp.h> 
#include <semaphore.h> 
#include <stack> 
using namespace std; 
sem_t empty,full; 
stack<int> stk; 
void produce(int i) 
{ 
    { 
    sem_wait(&empty); 
      cout<<"produce "<<i*i<<endl; 
      stk.push(i*i); 
    sem_post(&full); 
    } 
} 
void consume1(int &x) 
{ 
    sem_wait(&full); 
      int data=stk.top(); 
      stk.pop(); 
      x=data; 
    sem_post(&empty); 
} 
void consume2() 
{ 
    sem_wait(&full); 
      int data=stk.top(); 
      stk.pop(); 
      cout<<"consume2 "<<data<<endl; 
    sem_post(&empty); 
} 
int main() 
{ 
    sem_init(&empty,0,1); 
    sem_init(&full,0,0); 
    pthread_t t1,t2,t3; 
    omp_set_num_threads(3); 
    int TID=0; 
    #pragma omp parallel private(TID) 
    { 
      TID=omp_get_thread_num(); 
      if(TID==0) 
      { 
      cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 
      for(int i=0;i<5;i++) 
        produce(i); 
      } 
      else if(TID==1) 
      { 
        int x; 
        while(true) 
        { 
          consume1(x); 
          cout<<"consume1 "<<x<<endl; 
        } 
      } 
      else if(TID==2) 
      { 
        int x; 
        while(true) 
        { 
          consume1(x); 
          cout<<"consume2 "<<x<<endl; 
        } 
      } 
    } 
    return 0; 
} 

En primer lugar, puedo compilar usando:

g++ test.cpp -fopenmp -lpthread 

Y, me dio la respuesta correcta, hay 3 hilos totalmente.

Pero, cuando lo haga la compilación de esta manera:

g++ -c test.cpp -o test.o 
g++ test.o -o test -fopenmp -lpthread 

sólo hay sólo un hilo.

Cualquiera me puede decir cómo compilar este código correctamente. Gracias de antemano.

+3

Creo que los pragmas OpenMP se ignoran a menos que tenga '-fopenmp'. Por lo tanto, necesitará '-fopenmp' en todos los módulos que tengan pragmas OpenMP. – Mysticial

+0

@Mysticial ¿Crees que debería agregar -fopenmp cuando compilo el archivo .cpp a .o? –

+1

Sí. Pruebe 'g ++ -c test.cpp -o test.o -fopenmp'. Lo convertiré en una respuesta si funciona. – Mysticial

Respuesta

15

Los pragmas de OpenMP solo se habilitan cuando se compilan con -fopenmp. De lo contrario, son completamente ignorados por el compilador. (Por lo tanto, solo 1 hilo ...)

Por lo tanto, deberá agregar -fopenmp a la compilación de cada módulo que use OpenMP. (En lugar de sólo la etapa de unión final.)

g++ -c test.cpp -o test.o -fopenmp 
g++ test.o -o test -fopenmp -lpthread 
22

OpenMP es un conjunto de código transformar pragmas, es decir, que sólo se aplican en tiempo de compilación. No puede aplicar la transformación de código a un código de objeto ya compilado (vale, puede hacerlo, pero implica mucho más proceso y está fuera del alcance de lo que hacen la mayoría de los compiladores). Necesita -fopenmp durante la fase de enlace solo para que el compilador vincule automáticamente la biblioteca de tiempo de ejecución de OpenMP libgomp - no hace nada más con el código del objeto.

En una nota lateral, aunque técnicamente correcto, su código hace OpenMP de una manera muy no OpenMP. Primero, ha vuelto a implementar el constructo OpenMP sections. La región paralela en su función main podría reescribirse de manera más OpenMP:

#pragma omp parallel sections 
{ 
    #pragma omp section 
    { 
     cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 
     for(int i=0;i<5;i++) 
      produce(i); 
    } 
    #pragma omp section 
    { 
     int x; 
     while(true) 
     { 
      consume1(x); 
      cout<<"consume1 "<<x<<endl; 
     } 
    } 
    #pragma omp section 
    { 
     int x; 
     while(true) 
     { 
      consume1(x); 
      cout<<"consume2 "<<x<<endl; 
     } 
    } 
} 

(si se obtiene SIGILL mientras se ejecuta este código con más de tres hilos de OpenMP, se ha encontrado un error en GCC, que será arreglado en la próxima versión)

En segundo lugar, es posible que desee echar un vistazo a la construcción OpenMP task. Con él puede poner en cola piezas de código que se ejecutarán simultáneamente como tareas por cualquier hilo inactivo. Desafortunadamente, requiere un compilador que admita OpenMP 3.0, que excluye MSVC++ de la ecuación, pero solo si le importa la portabilidad a Windows (y obviamente no, porque está utilizando subprocesos POSIX).

+3

+1 para ir más allá de la llamada, el deber de realmente mirar el código del OP más de cerca. – Mysticial

Cuestiones relacionadas