2012-05-14 23 views
5

OpenMP kullanarak basit bir uygulama yazmaya çalışıyorum. Ne yazık ki hızlanma ile ilgili bir sorunum var. Bu uygulamada bir süre döngü var. Bu döngünün gövdesi, sıralı ve döngü için yapılması gereken bazı talimatlardan oluşur. Paralel için bunu yapmak için #pragma omp parallel for kullanıyorum. Bu döngüde fazla iş yok ama çok sık denir.OpenMP - sadece bir kere iş parçacığı oluştur

For döngüsünün iki sürümünü hazırlarım ve uygulamayı 1, 2 ve 4 karakterde çalıştırıyorum.
sürüm 1 (döngü için 4 tekrar): 22sec, 23sec, 26sec.
sürüm 2 (döngü için 100000 yineleme): 20sn, 10sn, 6sn.

Gördüğünüz gibi, döngü için fazla iş olmadığı zaman, 2 ve 4 çekirdekte zaman 1core'dan yüksek. Sanırım, neden #pragma omp parallel for, döngü sırasında her yinelemede yeni iş parçacığı oluşturuyor. Bu yüzden size sormak istiyorum - iş parçacığı oluşturmadan önce (döngüden önce) ve döngüdeki bazı işlerin sıralı olarak yapılmasını sağlamak için bir olasılık var mı?

#include <omp.h> 
#include <iostream> 
#include <math.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
int main(int argc, char* argv[]) 
{ 
    double sum = 0; 
    while (true) 
    { 
     // ... 
     // some work which should be done sequentially 
     // ... 

     #pragma omp parallel for num_threads(atoi(argv[1])) reduction(+:sum) 
     for(int j=0; j<4; ++j) // version 2: for(int j=0; j<100000; ++j) 
     { 
      double x = pow(j, 3.0); 
      x = sqrt(x); 
      x = sin(x); 
      x = cos(x); 
      x = tan(x); 
      sum += x; 

      double y = pow(j, 3.0); 
      y = sqrt(y); 
      y = sin(y); 
      y = cos(y); 
      y = tan(y); 
      sum += y; 

      double z = pow(j, 3.0); 
      z = sqrt(z); 
      z = sin(z); 
      z = cos(z); 
      z = tan(z); 
      sum += z; 
     } 

     if (sum > 100000000) 
     { 
      break; 
     } 
    } 
    return 0; 
} 

cevap

5

Sen while (true) döngünün dışına paralel bölgesini taşımak ve kod seri kısmı sadece bir thread çalıştırmak için yapmak single direktifini kullanabilirsiniz. Bu çatal/katılma modelinin yükünü kaldıracaktır. Ayrıca OpenMP, çok az sayıda yineleme ile (sürüm 1'iniz gibi) thight döngülerinde gerçekten yararlı değildir. Temelde döngü içinde çalışma gerçekten hızlı bir şekilde yapıldığından OpenMP yükünü ölçüyorsunuz - aşkın işlevlerle 100.000 yineleme bile mevcut nesil CPU'da saniyeden azını alır (2 GHz'de ve ek olarak FP araç başına kabaca 100 döngüde) ~ 100 ms al.

OpenMP seçici küçük döngüler için paralelleştirilmesi kapatmak için kullanılabilir if(condition) maddesini sağlar yüzden

: Aynı zamanda düzenli döngüler için schedule(static) (yani döngüler içindir kullanılması tavsiye edilir

#omp parallel for ... if(loopcnt > 10000) 
for (i = 0; i < loopcnt; i++) 
    ... 

hangi her yineleme hesaplamak için aynı zaman alır).

8

Çoğu OpenMP uygulaması, program başlangıcında bir dizi ileti dizisi oluşturur ve bunları program süresince saklar. Yani, çoğu uygulama, yürütme sırasında iş parçacıklarını dinamik olarak oluşturmaz ve yok etmez; Bunu yapmak, ciddi iş parçacığı yönetim maliyetleri ile performansa çarpacaktır. İş parçacığı yönetimine bu yaklaşım, OpenMP için olağan kullanım durumları ile uyumludur ve uygundur.

OpenMP iş parçacığı sayısını artırdığınızda gördüğünüz yavaşlamanın, çok az sayıda yinelemeli bir döngüde paralel ek yük oluşturmayacağı çok daha olasıdır. Hristo'nun cevabı bunu kapsamaktadır.

İlgili konular