Witam serdecznie :). To mój pierwszy post na forum, więc z góry chciałbym przeprosić za ewentualne wpadki i błędy merytoryczne.
Program o którym mowa w temacie, to nic innego jak C++ z wykorzystaniem bibliotek MPI lub OpenMP (tutaj do wyboru).
Ma on za zadanie obliczać miejsce zerowe jakiejkolwiek funkcji (może być jedna konkretna "wbudowana" w kod programu) wykorzystując jednocześnie "potencjał" (wyjaśnienie poniżej)* naszego procesora. Głównym zadaniem tego programu jest zmierzenie czasu (w milisekundach), w którym następują obliczenia przy użyciu 1,2,3,4 wątków itd. Ilość wykorzystywanych wątków może być zmieniana bezpośrednio w kodzie programu
-pod tym względem moje CPU, A64 X2 4200+, odpada z racji posiadania jedynie 2 rdzeni i 2 wątków. Tymczasowo będę miał jednak dostęp do Intel Core i3 posiadającego już 4 wątki, więc minimum wymagań sprzętowych spełnię.
Teraz najważniejsze pytanie.. jak to zrobić, żeby działało ok?
Z tego co wiem, wystarczy mieć prosty program w C++ obliczający miejsca zerowego oraz zaaplikować mu biblioteki openMP, z odpowiednimi parametrami. Znajomy z kolei polecił mi poszukał przykłądy do OpenMP i dodał w niego jakąś funkcję.
Używam Dev-C++ z dodaną obsługą MPI, jednak rozważam przejście na Visual Studio (tam mam od razu OpenMP bez kombinowania, no i z Dev'em pod górę mam trochę ;/
Znalazłem dość dobrze opisany kod programu w OpenMP, jednak mam problem w przekształceniu go obliczanie miejsca zerowego
#include <omp.h>
#include <stdio.h>
// kompilacja: gcc -fopenmp openmp.c -o openmp_demo
// uruchomienie (4 wątki): env OMP_NUM_THREADS=4 ./openmp_demo
int main (int argc, char *argv[]) {
int ilosc_watkow = -22, numer_watka = -33;
// od tego miejsca kod bedzie zrownoleglany ...
// default(none) wymusza jawne deklarowanie zasięgu każdej zmiennej
// zmienna prywatna dla kazdego z watkow bedzie numer_watka
// wspólną zmienną będzie ilosc_watkow
#pragma omp parallel default(none) shared(ilosc_watkow) private(numer_watka)
// ponadto w dyrektywie parallel możemy:
// określić kiedy ma mieć miejsce zrównoleglenie - poprzez if (warnunek na jakis zmiennych)
// ile wątków powinno obsługiwać urównoleglenie - poprzez num_threads(ilosc)
{
// poniższy blok wykona się tylko w pojedyńczym wątku
#pragma omp single
{
ilosc_watkow = omp_get_num_threads();
printf("Urównolegliliśmy się na %d watków\n", ilosc_watkow);
}
// poniższy kod wykona każdy z wątków niezależnie
numer_watka = omp_get_thread_num();
printf("Tu wątek numer %d ... ja żyje :-)\n", numer_watka);
// czekamy az wszystkie watki zakoncza powyzszy kod
#pragma omp barrier
if ( numer_watka == 0 ) { // tylko w watku zerowym
printf("Tu wątek numer zero ... informuje iż każdy wątek ma już ustawioną swoją zmienną numer_watka\n");
}
// możemy też w prostrzy od pokazanego powyżej if'a przydzielać zadania poszczególnym wątkom:
#pragma omp sections
{
#pragma omp section
{
// ten wątek sobie troszkę pośpi
sleep(1)
printf("Jakiś wątek AAAA\n");
}
#pragma omp section
{
printf("Jakiś inny wątek BBBB\n");
}
}
}
printf("No i nie ma już naszych %d wątków ... ", ilosc_watkow);
printf("teraz mamy zwykły sekwencyjnie wykonywany program, a numerem wątka jest %d\n", numer_watka);
// na powyższym widać różnicę między zmienną współdzieloną a prywatną dla wątków
// możemy urównoleglać także petlę for
// możemy używać zmiennej do której pisac będzie kilka wątków
// pod warunkiem że będzie to tablica a watki piszą do różnych komórek
// lub że będzie to zmienna akumulacyjna (jak w poniższym przykładzie)
// - musi być ona wtedy podana przez reduction(charakter:zmienna)
int i, max_i=10, suma=0;
#pragma omp parallel for default(none) shared(max_i) private(i) reduction(+ : suma)
for (i = 0; i < max_i; i++) {
suma += i * omp_get_thread_num();
}
printf("SUMA = %d\n", suma);
}
Poratuje ktoś?