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.