OpenMP Synchronization Constructs
- Sevdanur GENC

- Mar 12, 2013
- 2 min read
Synchronization Constructs konu basligi altinda Critical Constructs, Atomic Constructs ve Barrier Constructs yapilarini birer ornekle aciklamaya calisacagim. Ayni zamanda Reduction Clause yapisi hakkindada bir ornek paylasiyor olacagim.
Critical Constructs Yapisi;
Critical clause yapilari birim zamanda tek bir thread'de tek bir islemi gerceklestirebilmek icin kullanilmaktadir. Kullanilan degiskenin bir havuza girmeden once bir thread tarafindan degistirilmesi gerekmektedir. Single Clause yapisi ile ayni isi yapar fakat farki diger thread'ler beklemiyor ve bu durumda hemen calismaya basliyorlar.
Critical.Cpp Kaynak Kodu;
#include <stdio.h>
#include <omp.h>
#include <conio.h>
int main()
{
int n = 9 ,i, ThreadID, Toplam=0, LocalToplam;
#pragma omp parallel private(i, ThreadID, LocalToplam) shared(n, Toplam)
{
ThreadID = omp_get_thread_num();
LocalToplam=0;
#pragma omp for
for (i=0; i<n; i++)
LocalToplam += i;
#pragma omp critical
{
Toplam += LocalToplam;
printf("ThreadID = %d: Local Toplam = %d, Toplam = %d\n", ThreadID, LocalToplam, Toplam);
}
}
printf("Paralel Havuzdan sonraki toplam : %d\n", Toplam);
getche();
}
Ekran Ciktisi;
Barrier Constructs Yapisi;
Mantik, Thread'lerin bir noktadan sonra senkronizasyon seklinde yaptiklari islemlere devam etmesini istiyoruz. Barrier ifadesinden once bir paralel havuz bulunduruyor ve farkli kodlar barindiriyorsaniz, thread sayisina gore farkli islemler yapiyor olacaktir. Barrier ifadesini gordukten sonra yuk dengeleme islemini duzenli bir sekilde yapmamiz gerekecektir. Hepsi ayni anda senkronizasyona dusebilmesi icin bu kodu kullaniyor olacagiz. Aslinda yeni bir paralel havuz olusturulmus gibi dusunulup icerisindeki butun thread'leri kullanabiliyor olacagiz.
Barrier.Cpp Kaynak Kodu;
#include <stdio.h>
#include <omp.h>
#include <conio.h>
int main()
{
int ThreadID;
#pragma omp parallel private(ThreadID)
{
ThreadID = omp_get_thread_num();
if (ThreadID < omp_get_num_threads()/2 ) printf("Hello!\n");
printf("Barrier Oncesi Thread No : %d\n", omp_get_thread_num());
#pragma omp barrier
printf("Barrier Sonrasi Thread No : %d\n", omp_get_thread_num());
}
getche();
}
Ekran Ciktisi;
Atomic Constructs Yapisi;
Birden fazla thread ayni anda calistigini dusundugumuzde sadece bir thread, ayni anda ortak kullanilabilecek bir degiskeni gorur ve bu degiskenin diger thread'ler tarafindan kullanilmasi halinde bilgiyi guncellemesi gerekmektedir. Diger bir onemli husus ise Atomic yapi aslinda paralel havuzda default bir degerdedir.
Atomic.Cpp Kaynak Kodu;
#include <stdio.h>
#include <omp.h>
#include <conio.h>
int main()
{
int n=0; float x=0.0;
#pragma omp parallel
{
#pragma omp atomic
n++;
#pragma omp atomic
x += 1.0f;
printf("n 'nin degeri : %d, x 'in degeri : %f \n", n, x);
}
getche();
}
Ekran Ciktisi;
Reduction Clause Yapisi;
Amac paralel kodlarinizdaki veriler uzerinde calisirken hiz onemliyse reduction kullanilmaktadir. Her thread farkli bir veri bolgesini ustlenmis ve islemektedir. En sonunda ise bunlari birlestirme islemi yapilmakta ve esas sonuca varilmaktadir. Bunun icinde paralel havuz icerisinde Reduction ifadesini gormesi yeterli olacaktir. Mesela reduction(+:result) seklinde bir ifademiz bulunmakta burada : 'den onceki ifade aritmatik bir islem olmaktadir, sonraki ifade ise parcalarin sonuclarini hangi degiskende topluyorsak onu belirtmemiz gerekiyor. Ornek verecek olursak;
Reduction.Cpp Kaynak Kodu;
#include <stdio.h>
#include <omp.h>
#include <conio.h>
int main()
{
int n = 10, i, topla =0;
#pragma omp parallel for private(i) shared(n) reduction(+:topla)
for (i=0; i<=n; i++)
topla += i;
printf("Paralel bolgeden gelen toplam sonuc : %d\n", topla);
getche();
}
Ekran Ciktisi;
Keyifli Calismalar Dilerim...
Comments