OpenMP azaltmaları
PI’nin #pragma omp azaltma yan tümcesi kullanılarak yaklaştırılması
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h) reduction(+:area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
Bu örnekte, her iş parçacığı yineleme sayısının bir alt kümesini yürütür. Her iş parçacığının kendi yerel özel ‘alan’ kopyası vardır ve paralel bölgenin sonunda hepsi, ‘alan’ için son değeri oluşturmak üzere toplama işlemini (’+’) uygular.
#Pragma omp kritik tabanlı indirgemeler kullanılarak PI’nin yaklaştırılması
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h, area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
#pragma omp critical
{
area += (4.0 / (1.0 + x*x));
}
}
pi = h * area;
Bu örnekte, her bir iş parçacığı yineleme sayısının bir alt kümesini yürütür ve paylaşılan değişken “alan"da atomik olarak birikir, bu da hiçbir güncellemenin kaybolmamasını sağlar.
PI’nin #pragma atomik temelli indirgemeler kullanılarak yaklaştırılması
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h, area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
#pragma atomic
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
Bu örnekte, her bir iş parçacığı yineleme sayısının bir alt kümesini yürütür ve paylaşılan değişken “alan"da atomik olarak birikir, bu da hiçbir güncellemenin kaybolmamasını sağlar. Burada #pragma atomic
kullanabiliyoruz çünkü verilen işlem (+=
) atomik olarak yapılabiliyor, bu da #pragma omp kritik
kullanımına kıyasla okunabilirliği basitleştiriyor.
PI’nin el yapımı #pragma omp azaltmasının yaklaşıklığı
h = 1.0 / n;
#pragma omp parallel private(x) shared(n, h)
{
double thread_area = 0; // Private / local variable
#pragma omp for
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
thread_area += (4.0 / (1.0 + x*x));
}
#pragma omp atomic // Applies the reduction manually
area += thread_area; // All threads aggregate into area
}
pi = h * area;
Konular “#pragma omp parallel” içinde oluşturulur. Her iş parçacığı, kısmi eklemesini depolayan bağımsız/özel bir “thread_area"ya sahip olacaktır. Aşağıdaki döngü, “#pragma omp for” kullanılarak iş parçacıkları arasında dağıtılır. Bu döngüde, her iş parçacığı kendi “thread_area"sını hesaplar ve bu döngüden sonra kod, alanı “#pragma omp atomic” aracılığıyla sırayla atomik olarak toplar.