#Pragma omp parallel ve #pragma omp parallel arasındaki fark
Ben OpenMPyeniyim ve OpenMP kullanarak iki dizi ekleyen bir program çalıştırmaya çalışıyorum. OpenMP eğitimde, ben kullanmak gerekir öğrendik için #pragma OMP paralel üzerinde OpenMP kullanırken için döngü. Ama aynı şeyi #pragma omp paralel ile de denedim ve aynı zamanda bana doğru çıktıyı veriyor. Aşağıda iletmeye çalıştığım şeyin kod parçacıkları var.
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
ve
#pragma omp parallel
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
Bu ikisi arasındaki fark nedir?
Yanıtlar
The
#pragma omp parallel:
her bir iş parçacığının içerdiği kod bloğunun tamamını yürüteceği parallel regionbir takım ile bir oluşturacaktır .threadsparallel region
Gönderen OpenMP 5.1 birinin daha resmi bir açıklama okuyabilirsiniz:
Bir iş parçacığı bir karşılaştığında paralel yapısını , iş parçacığı bir ekip oluşturulur paralel bölgeyi (..) yürütmek için. Paralel yapıyla karşılaşan iş parçacığı, yeni paralel bölgenin süresi boyunca sıfır olan iş parçacığı numarasıyla yeni ekibin birincil iş parçacığı haline gelir. Yeni takımdaki birincil iş parçacığı dahil tüm iş parçacıkları bölgeyi yürütür. Takım oluşturulduktan sonra, takımdaki iş parçacığı sayısı o paralel bölgenin süresi boyunca sabit kalır.
:
#pragma omp parallel for
bir parallel region(daha önce açıklandığı gibi) oluşturacak ve threadsbu bölgeye , tipik olarak olan default chunk sizeve kullanılarak içerdiği döngünün yinelemeleri atanacaktır . Bununla birlikte, standardın farklı somut uygulamaları arasında farklılık gösterebileceğini unutmayın .default schedule staticdefault scheduleOpenMP
Gönderen OpenMP 5.1 Eğer daha resmi bir açıklama okuyabilirsiniz:
İş paylaşımı döngüsü yapısı, bir veya daha fazla ilişkili döngünün yinelemelerinin, örtük görevleri bağlamında takımdaki evreler tarafından paralel olarak yürütüleceğini belirtir. Yinelemeler, iş paylaşımı döngüsü bölgesinin bağlandığı paralel bölgeyi yürüten ekipte zaten var olan iş parçacıkları arasında dağıtılır .
Dahası ,
Paralel döngü yapısı, bir veya daha fazla ilişkili döngü içeren ve başka hiçbir ifade içermeyen bir döngü yapısı içeren paralel bir yapıyı belirtmek için bir kısayoldur.
Veya gayri resmi olarak, #pragma omp parallel forkurucu #pragma omp parallelile #pragma omp for. Sizin durumunuzda bu şu anlama gelir:
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
anlamsal ve mantıksal olarak şununla aynıdır:
#pragma omp parallel
{
#pragma omp for
for(int i=0;i<n;i++)
{
c[i]=a[i]+b[i];
}
}
TL; DR: ile örnekte, #pragma omp parallel fordöngü (parçacıkları arasında parallelized edilecek yani döngü yineleme parçacıkları arasında bölünecek) ile oysa #pragma omp parallel tüm iş parçacıkları (paralel) çalıştırır tüm döngü yinelemeleri.
Daha açıklayıcı hale getirmek için, 4konu #pragma omp parallelbaşlıkları ile aşağıdaki gibi bir sonuç elde edilir:
oysa #pragma omp parallel fora chunk_size=1ve statik aşağıdaki schedule gibi bir sonuç verir:
Kod açısından döngü mantıksal olarak aşağıdakine benzer bir şeye dönüştürülecektir :
for(int i=omp_get_thread_num(); i < n; i+=omp_get_num_threads())
{
c[i]=a[i]+b[i];
}
omp_get_thread_num () nerede
Omp_get_thread_num rutini, çağıran evrenin mevcut takım içindeki evre numarasını döndürür.
ve omp_get_num_threads ()
Mevcut takımdaki konu sayısını döndürür. Programın sıralı bir bölümünde omp_get_num_threads 1 değerini döndürür.
veya başka bir deyişle for(int i = THREAD_ID; i < n; i += TOTAL_THREADS),. İle THREAD_IDarasında değişen 0için TOTAL_THREADS - 1ve TOTAL_THREADSparalel bölge oluşturulan takım parçacığı toplam sayısını temsil eden.
For döngüsünde OpenMP'yi kullanırken #pragma omp paralel kullanmamız gerektiğini öğrendim. Ama aynı şeyi #pragma omp paralel ile de denedim ve aynı zamanda bana doğru çıktıyı veriyor.
Size aynı çıktıyı verir, çünkü kodunuzda:
c[i]=a[i]+b[i];
dizi ave dizi byalnızca okunur ve dizi c[i]güncellenen tek dizidir ve değeri yinelemenin kaç kez iyürütüleceğine bağlı değildir . Bununla birlikte, #pragma omp parallel forher iş parçacığı ile kendi kendini güncelleyecektir i, oysa #pragma omp paralleliş parçacıkları ile aynı is'leri güncelleyecek , dolayısıyla birbirlerinin değerlerini geçersiz kılacaktır.
Şimdi aynısını aşağıdaki kodla yapmayı deneyin:
#pragma omp parallel for
{
for(int i=0;i<n;i++)
{
c[i]= c[i] + a[i] + b[i];
}
}
ve
#pragma omp for
{
for(int i=0;i<n;i++)
{
c[i] = c[i] + a[i] + b[i];
}
}
farkı hemen fark edeceksiniz.
İkinci durumda, döngü paralelleştirilmez. Yani, tüm döngü, her evrede yürütülür . Genel olarak, paralel bölgenin içinde ne varsa, tüm iş parçacıkları tarafından yürütülür.
Ek olarak mevcut paralel bölgedeki döngüyü aşağıdaki gibi paralelleştirebilirsiniz:
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < n; i++)
c[i] = a[i] + b[i];
}