Wykorzystanie funkcji omp we wcześniej napisanych programach


(przemeks91) #1

Witam,

na ćwiczenia potrzebuję przy pomocy OpenMP przerobić któryś z moich wcześniejszych programów, tak, aby znajdowała się w nim "pragma omp ..." wykonująca pętlę for. Niestety za bardzo nie wiem jak się do tego zabrać, jak wykonać to ćwiczenie. Co będzie miało na celu zastosowanie "pragmy" w jednym z wymienionych programów? W jakim celu stosuje się fukncję omp. Oto przykładowe programy w języku C++:

  • Kalkulator

  • Program wyświetlający 2 liczby w kolejności jedna większa druga mniejsza.

  • Program dodający i wyświetlający sumę kolejno 4 podane przez uzytkownika liczby

- Program podnoszący liczby do dowolnej potęgi

  • Obliczanie pola prostokąta.

Może ktoś miałby pomysł na jeszcze inny prosty program, w którym lepiej można wykorzystać pragmę z pętlą for.


(Blady214) #2

OpenMP jest to biblioteka, która umożliwia programowanie współbieżne (wielowątkowe). Zastosowanie pragm umożliwi Ci rozdzielenie jednego procesu, złożonego obliczeniowego, pomiędzy kilkoma wątkami. Dzięki temu cały program wykona się znacznie szybciej. W programach, które wymieniłeś raczej nie zauważysz wpływu wprowadzenia pragm na czas wykonania programu.

 

Jeśli chcesz wykonać dobrze to ćwiczenie, możesz napisać program do mnożenia macierzy kwadratowych. Pamiętaj również, że przy pragmach musisz mieć na uwadze zależności. Polecam lekturę: https://computing.llnl.gov/tutorials/openMP/


(przemeks91) #3

Witam,

postanowiłem do programu kalkulator dodać pragmę umożliwiającą obliczanie silni. W związku z tym prosiłbym o sprawdzenie czy w tym przypadku dobrze została ona wykorzystana, oraz czy dobrze został napisany cały program. Chciałbym jeszcze zaznaczyć, że jestem początkujący, więc proszę o wyrozumiaość i pomoc.

#include <iostream.h>
void main(void)
{

int a,b,suma,roznica,iloczyn,iloraz,silnia;

cin>>a;
cin>>b;
suma=a+b;
cout<<"suma ="<<suma<<endl;

roznica=a-b;
cout<<"roznica = "<<roznica<<endl;

iloczyn=a*b;
cout<<"iloczyn = "<<iloczyn<<endl;

iloraz=a/b;
cout<<"iloraz = "<<iloraz<<endl;

silnia=1;
cout << "Podaj a=";  
  cin >> n;  

# pragma omp parallel for
for (i=1;i<=n;i++)  
    silnia=silnia*i;
}

(pebal) #4
#pragma omp parallel for 
for (i=1;i<=n;i++) 
  silnia=silnia*i;

Powyższy kod nie będzie działać prawidlowo, gdyż zmienna bedzie modyfikowana przez wiele wątków jednocześnie. To będzie prowadzić do przekłamań.

Każdy wątek powinen liczyć na własnej zmiennej a finalna zmienna powinna być modyfikowana w sekcji krytycznej (tylko jeden wątek modyfikuje zmienną w tym samym czasie).

#pragma omp parallel
{
  int s = 1;

  #pragma omp for nowait
  for (int i = 1; i <= n; i++)
    s *= i;

  #pragma omp critical
  {
    silnia *= s;
  }
}

(Blady214) #5

W przypadku zrównoleglenia, które zastosowałeś występuje zależność pomiędzy poszczególnymi iteracjami uniemożliwiająca poprawne zrównoleglenie. Co więcej nie dołączyłeś biblioteki.


(przemeks91) #6

Jak mam dołączyć tą bibliotekę?


(Blady214) #7

Tak jak każdą inną bibliotekę, czyli:

#include <omp.h>

W jakim systemie piszesz i z jakiego kompilatora korzystasz?


(pebal) #8

W Visual Studio trzeba jeszcze właczyć Open MP w opcjach projektu. Otworzyć “Project->Properties”, rozwinąć “Configuration Properties->C/C+±>Language” i ustawić opcję “Open MP Support” na Yes.


(przemeks91) #9

To po dodaniu biblioteki oraz wprowadzeniu wcześniej napisnych poprawek pragma powinna się wykonać?

Czy mógłby mi ktoś jeszcze krótko wytłumaczyć jak zadziała poprawiona pragma, co dany jej element oznacza?


(Blady214) #10

Masz na myśli to, co pebal napisał? Szczerze polecam Ci zapoznać się z tutorialem, który zamieściłem w jednym z wcześniejszych postów, ponieważ nie masz zielonego pojęcia na temat OpenMP.