Perbedaan antara #pragma omp parallel dan #pragma omp parallel for

Dec 11 2020

Saya baru OpenMPdan saya telah mencoba menjalankan program yang menambahkan dua array menggunakan OpenMP. Dalam tutorial OpenMP, saya telah belajar bahwa kita perlu menggunakan #pragma omp parallel untuk saat menggunakan OpenMP pada loop for . Tetapi saya juga mencoba hal yang sama dengan #pragma omp parallel dan itu juga memberi saya hasil yang benar. Di bawah ini adalah potongan kode dari apa yang ingin saya sampaikan.

#pragma omp parallel for
{
      for(int i=0;i<n;i++)
       {  
            c[i]=a[i]+b[i];
       }
}

dan

 #pragma omp parallel
{
      for(int i=0;i<n;i++)
       {  
            c[i]=a[i]+b[i];
       }
}

Apa perbedaan antara keduanya?

Jawaban

5 dreamcrash Dec 11 2020 at 15:14

Itu

#pragma omp parallel:

akan membuat parallel regiondengan tim threads, di mana setiap utas akan mengeksekusi seluruh blok kode yang parallel regiondisertakan.

Dari OpenMP 5.1 seseorang dapat membaca deskripsi yang lebih formal:

Ketika sebuah utas menemukan konstruksi paralel , tim utas dibuat untuk mengeksekusi wilayah paralel (..). Utas yang mengalami konstruksi paralel menjadi utas utama tim baru, dengan nomor utas nol selama wilayah paralel baru. Semua utas di tim baru, termasuk utas utama, menjalankan wilayah tersebut. Setelah tim dibuat, jumlah utas dalam tim tetap konstan selama wilayah paralel tersebut.

Itu:

#pragma omp parallel for

akan membuat parallel region(seperti yang dijelaskan sebelumnya), dan ke threadswilayah itu iterasi loop yang dilingkupinya akan ditetapkan, menggunakan default chunk size, dan default scheduleyang biasanya static . Ingatlah, bagaimanapun, bahwa default schedulemungkin berbeda di antara penerapan konkret yang berbeda dari OpenMPstandar.

Dari OpenMP 5.1 Anda dapat membaca deskripsi yang lebih formal:

Konstruksi worksharing-loop menentukan bahwa iterasi dari satu atau lebih loop terkait akan dieksekusi secara paralel oleh thread dalam tim dalam konteks tugas implisitnya. Iterasi didistribusikan di seluruh utas yang sudah ada di tim yang menjalankan wilayah paralel yang mengikat wilayah loop berbagi kerja .

Selain itu ,

Konstruksi loop paralel adalah jalan pintas untuk menentukan konstruksi paralel yang berisi konstruksi loop dengan satu atau lebih loop terkait dan tidak ada pernyataan lain.

Atau secara informal, #pragma omp parallel formerupakan kombinasi konstruktor #pragma omp paralleldengan #pragma omp for. Dalam kasus Anda, ini berarti:

#pragma omp parallel for
{
      for(int i=0;i<n;i++)
       {  
            c[i]=a[i]+b[i];
       }
}

secara semantik, dan logis, sama dengan:

#pragma omp parallel
{
      #pragma omp for
      for(int i=0;i<n;i++)
       {  
            c[i]=a[i]+b[i];
       }
}

TL; DR: Dalam contoh Anda, dengan #pragma omp parallel forloop akan diparalelkan di antara utas ( yaitu, iterasi loop akan dibagi di antara utas), sedangkan dengan #pragma omp parallel semua utas akan mengeksekusi (secara paralel) semua iterasi loop.

Untuk membuatnya lebih ilustratif, dengan 4utas tersebut #pragma omp parallel, akan menghasilkan sesuatu seperti:

sedangkan #pragma omp parallel fordengan a chunk_size=1dan statis schedule akan menghasilkan sesuatu seperti:

Dari segi kode, loop akan diubah menjadi sesuatu yang secara logis mirip dengan:

for(int i=omp_get_thread_num(); i < n; i+=omp_get_num_threads())
{  
    c[i]=a[i]+b[i];
}

dimana omp_get_thread_num ()

Rutin omp_get_thread_num mengembalikan nomor thread, dalam tim saat ini, dari thread pemanggil.

dan omp_get_num_threads ()

Mengembalikan jumlah utas di tim saat ini. Di bagian berurutan dari program omp_get_num_threads mengembalikan 1.

atau dengan kata lain for(int i = THREAD_ID; i < n; i += TOTAL_THREADS),. Dengan rentang THREAD_IDdari 0hingga TOTAL_THREADS - 1, dan TOTAL_THREADSmewakili jumlah total utas tim yang dibuat di wilayah paralel.

Saya telah belajar bahwa kita perlu menggunakan paralel #pragma omp untuk sementara menggunakan OpenMP pada perulangan for. Tetapi saya juga mencoba hal yang sama dengan #pragma omp parallel dan itu juga memberi saya hasil yang benar.

Ini memberi Anda hasil yang sama, karena dalam kode Anda:

 c[i]=a[i]+b[i];

array adan array bhanya dibaca, dan array c[i]adalah satu-satunya yang diperbarui, dan nilainya tidak bergantung pada berapa kali iterasi iakan dijalankan. Namun demikian, dengan #pragma omp parallel forsetiap utas akan memperbarui sendiri i, sedangkan #pragma omp parallelutas akan memperbarui yang sama i, sehingga menimpa nilai satu sama lain.

Sekarang coba lakukan hal yang sama dengan kode berikut:

#pragma omp parallel for
{
      for(int i=0;i<n;i++)
       {  
            c[i]= c[i] + a[i] + b[i];
       }
}

dan

#pragma omp for
{
      for(int i=0;i<n;i++)
       {  
            c[i] = c[i] + a[i] + b[i];
       }
}

Anda akan segera melihat perbedaannya.

2 DanielLangr Dec 11 2020 at 15:16

Dalam kasus kedua, loop tidak diparalelkan. Yakni, seluruh loop dijalankan di setiap utas . Umumnya, apa pun yang ada di dalam wilayah paralel dijalankan oleh semua utas.

Anda juga dapat memparalelkan loop di region paralel yang sudah ada sebagai berikut:

#pragma omp parallel
{
  #pragma omp for
  for (int i = 0; i < n; i++)
    c[i] = a[i] + b[i];
}