#parallel ile for
Açıklaması şöyle. Blok içindeki kodu işleyen N tane thread başlatılır.
Şöyle yaparız
Şöyle yaparız.Her thread bir section kodunu çalıştırır.
Örnek
Şöyle yaparız. Single producer her nesneyi kuyruğa koyar. task'lar ise kuyruktan okurlar.
Şöyle yaparız.
Şöyle yaparız.
Söz dizimi şöyle.
Şöyle yaparız.
Şöyle yaparız.
Şöyle yaparız.
Şöyle yaparız. Paralel kodun 4 thread tarafından çalıştırılmasını sağlar.
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ızid = 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 reductionSö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