11 Mayıs 2018 Cuma

OpenMP parallel - Blok içindeki kodu işleyen N tane thread başlatılır

#parallel ile for
Açıklaması şöyle. Blok içindeki kodu işleyen N tane thread başlatılır.
#pragma omp parallel spawns a group of threads, while #pragma omp for divides loop iterations between the spawned threads.
Şöyle yaparız.
#pragma omp parallel
{
  #pragma omp for
  for (int i=0;i<NX;i++)
  {
    ...
  }
  #pragma omp for 
  for (int i=1;i<NX-1;i++)
  {
    ...
  }
}
#parallel ile threadprivate
Şöyle yaparız
static int dataVersion;

data_t& GetData()
{
    static data_t *d = NULL;
    #pragma omp threadprivate(d); // !!!

    if (d && d->myDataVersion != dataVersion) {
        delete d;
        d = nullptr;
    }
    if (!d) { 
        d = new data_t();
        d->myDataVersion = dataVersion;
    }

    return *d;
}
#parallel ile section
Şöyle yaparız.Her thread bir section kodunu çalıştırır.
#pragma omp parallel sections
{
  #pragma omp section
  { 
    printf ("id = %d, \n", omp_get_thread_num());/* Executes in thread 1 */
  }

  #pragma omp section
  { 
    printf ("id = %d, \n", omp_get_thread_num());/* Executes in thread 2 */
  }
}
Çıktı olarak şunu alırız
id = 0,
id = 1,
Çalışma şekli şöyledir. N tane thread başlatılır. Sadece iki tanesi çalışır, diğerleri bekler. Thread 1 kısa sürede biter. Thread 2 biraz daha uzun çalışır. Tüm thread'ler sections sonundaki bariyerdel (* işareti) buluşurlar.
                 [    sections     ]
Thread 0: -------< section 1 >---->*------
Thread 1: -------< section 2      >*------
Thread 2: ------------------------>*------
...                                *
Thread N-1: ---------------------->*------
#parallel ile single
Örnek
Şöyle yaparız. Single producer her nesneyi kuyruğa koyar. task'lar ise kuyruktan okurlar.
#pragma omp parallel
{
  #pragma omp single
  {
    for (auto x : stl_container)
    {
      #pragma omp task
      {
        // Do something with x, e.g.
        compute(x);
      }
    }
  }
}
Çalışma şekli şöyledir.
               +--+-->[ task queue ]--+
               |  |                   |
               |  |       +-----------+
               |  |       |
Thread 0: --< single >-|  v  |-----
Thread 1: -------->|< foo() >|-----
Thread 2: -------->|< bar() >|-----
Örnek
Şöyle yaparız.
#pragma omp parallel num_threads(2)
{
  #pragma omp single
  QuickSort(arr, 0, arr.length, cuttoff);
}
#parallel ile thread sayısı
Şöyle yaparız.
#pragma omp parallel num_threads (10)
{
  ...
}
Şöyle yaparız.
#pragma omp parallel num_threads(3)
#pragma omp for
{
  ...
}
#parallel ile reduction
Söz dizimi şöyle.
reduction(operation:var)  
Açıklaması şöyle.
Note that reduction variables are private and their intermediate values (i.e. the value they hold before the reduction at the end of the parallel region) are only partial and not very useful.
Örnek
Şöyle yaparız.
#include <iostream>
#include <omp.h>

struct dbl_int {
    double val;
    int idx;
};

const dbl_int& max( const dbl_int& a, const dbl_int& b) {
  return a.val > b.val ? a : b;
}

#pragma omp declare reduction( maxVal: dbl_int: omp_out=max( omp_out, omp_in ) )

int main() {
  dbl_int di = { -100., -1 };
  #pragma omp parallel num_threads( 10 ) reduction( maxVal: di )
  {
    di.val = omp_get_thread_num() % 7;
    di.idx = omp_get_thread_num();
  }
    
  return 0;
}
Örnek
Şöyle yaparız.
//g++ -O3 -Wall foo.cpp -fopenmp
#pragma omp parallel for reduction(+:sum)
for(int i = 0 ; i < 2000000000; i++)
 sum += i%11;
#parallel İçinde critical + barrier
Şöyle yaparız.
#pragma omp parallel
{
   ...

  #pragma omp critical(iteration) //Scope için mutex koy
  {
    iteration++; //Bir değişkeni artır
  }
  ...

  #pragma omp critical(reduction) //If için mutex koy
  if (...)
  {
    ...
  }

  #pragma omp barrier //Tüm thread'lerin bitmesini bekle
   ...
}
#pragma İçinde dynamic
Şöyle yaparız. Paralel kodun 4 thread tarafından çalıştırılmasını sağlar.
#pragma omp parallel
{
   #pragma omp for schedule(dynamic,4)
   for (i = 0; i < N; i++)
   {
     ...
   }
   ...
}
İptal Etme
OpenMP 2'de iptal etmek yapıları yok. OpenMP 4 ile geldi. Şöyle yaparız.

Hiç yorum yok:

Yorum Gönder