C++ OpenMP

Da Andreabont's Wiki.

OpenMP è una libreria per C/C++ che permette di parallelizzare il codice con maggior semplitità.

Compilare ed eseguire

g++ -std=c++11 -fopenmp <file_sorgente>

L'eseguibile leggerà dalla variabile d'ambiente OMP_NUM_THREADS quanti thread utilizzare per eseguire il programma compilato, è possbile personalizzare questa variabile tramite il comando bash:

export OMP_NUM_THREADS=10

Clausole sulle variabili passate ai thread

E' possibile passare delle variabili ai thread generati, per farlo è necessario specificare come vengono passate e come i thread possano usarle.

Clausola Descrizione
private Ogni thread avrà una sua copia di quella variabile inizializzata con il valore della variabile iniziale.
shared Queste variabili sono condivise tra i thread (causa problemi di concorrenza)

Costrutto per creare thread

Il seguente costrutto permette di creare dei thread a partire dal punto in cui è dichiarato, i thread condivideranno il codice che segue.

#pragma omp parallel

Esempio

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

int main (int argc, char *argv[])
{
   int nthreads, tid;

   /* Creo altri tread passando delle copie private (una per ogni thread) di nthreads e tid */
   #pragma omp parallel private(nthreads, tid)
   {

      /* Ottengo ID del thread */
      tid = omp_get_thread_num();
      printf("Hello World from thread = %d\n", tid);

      /* Solo il thread master entra nel if (TID = 0) */
      if (tid == 0) {
         nthreads = omp_get_num_threads();
         printf("Number of threads = %d\n", nthreads);
      }
    
   }  /* Tutti i thread terminano */
  
}

Costrutto per condividere il carico

Con questo costrutto possiamo parallelizzare il carico su più thread, è spesso usato nei cicli, ogni thread esegue solo una parte dei cicli totali.

#pragma omp parallel for

Esempio

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

int main (int argc, char *argv[]) 
{
   
   int x, tid; 
   #pragma omp parallel for
   for(x=0; x < 10; x++) {
      tid = omp_get_thread_num();
      printf("Tread %d, X = %d\n", tid,x);
   }

}