Salta al contingut

    ↑ ↓ per moure't↵ per obrir

    Descomposició de tasques · 3.2

    Models d'execució: tasques implícites i explícites

    Un cop tens el team, OpenMP et dona dos models: tasques implícites (cada thread executa el bloc) i tasques explícites (un thread crea tasques a una pool i tots les agafen).

    Conceptes clau

    • Tasques implícites (paral·lelisme per threads)
    • omp_get_num_threads i omp_get_thread_num
    • Tasques explícites (task)
    • single i la pool de tasques
    • Separació entre creació i execució

    Un cop creat el team, OpenMP ofereix dos enfocaments per explotar el paral·lelisme: paral·lelisme per threads (tasques implícites) i paral·lelisme per tasques (tasques explícites).

    Tasques implícites: paral·lelisme per threads

    En crear el team, OpenMP assigna a cada thread una tasca implícita corresponent al cos del bloc parallel: tots els threads executen el mateix fragment de codi simultàniament. Per repartir la feina, podem consultar el nombre total de threads i l’identificador de cadascun, i així fer que cada thread processi una part diferent de les dades:

    int nt = omp_get_num_threads(); // nombre total de threads del team
    int id = omp_get_thread_num();  // id del thread actual (0 .. nt-1)
    
    #pragma omp parallel num_threads(N)
    {
        // cada thread executa aquest bloc com a tasca implicita
    }

    Tasques explícites: paral·lelisme per tasques

    Les tasques explícites es creen manualment amb la directiva #pragma omp task. En lloc d’assignar feina directament a cada thread, un thread s’encarrega de crear les tasques i dipositar-les en una pool de tasques, d’on els threads les agafen i executen de forma dinàmica.

    Per evitar que tots els threads creïn les mateixes tasques, s’utilitza la directiva #pragma omp single, que garanteix que només un thread executa el bloc de creació, mentre la resta esperen que hi hagi tasques a la pool:

    #pragma omp parallel
    #pragma omp single
    {
        #pragma omp task
        {
            // codi de la tasca
        }
    }

    La clau d’aquest model és la separació entre creació i execució: una tasca pot executar-se més tard i per un thread diferent del que l’ha creada. Això permet una distribució de càrrega molt més flexible que el model de tasques implícites.