Forum » Programiranje » [C++] OpenMP težave
[C++] OpenMP težave
Arto ::
EDIT:
Napaka popravljena, ampak še vedno potrebuje zadeva več časa pri paralelni metodi kot pri sekvenčni.
Napaka popravljena, ampak še vedno potrebuje zadeva več časa pri paralelni metodi kot pri sekvenčni.
// OpenMP.cpp : Defines the entry point for the console application. // #include "stdlib.h" #include "stdio.h" #include "Windows.h" #include "time.h" #include "omp.h" #define N 50000000 #define N_THREADS 2 int max_num(int a_size, int a[]){ int i; int max = 0; for(i=0; i<a_size; i++){ if(a[i] > max) max = a[i]; } return max; } int max_num_p(int a_size, int a[]){ int i, tn, max[N_THREADS]; //omp_set_num_threads(N_THREADS); #pragma omp parallel for shared(a,max) private(tn) for(i=0; i<a_size; i++){ //if(i==1)printf("Num: %d\n", omp_get_num_threads()); tn = omp_get_thread_num(); //printf("Thread %d - i=%d\n", tn, i); if(max[tn]<a[i]){ max[tn]=a[i]; } } /*for(i=0; i<N_THREADS; i++){ printf("%d\n", max[i]); }*/ return max_num(N_THREADS, max); } void fill_random(int a_size, int a[]){ int i; srand( time(NULL) ); for(i=0; i<a_size; i++){ a[i]=rand(); } } int main(int argc, char * argv[]) { int start,stop, time; int * a; a = (int *)malloc(N * sizeof(int)); int max; fill_random(N, a); printf("Start:\n"); start = clock(); max = max_num(N, a); stop = clock(); time = stop-start; printf("%d t:%d\n", max, time); start = clock(); max = max_num_p(N, a); stop = clock(); time = stop-start; printf("%d t:%d\n", max, time); free(a); system("pause"); return 0; }
- spremenil: Arto ()
Rokm ::
Namesto
uporabi
Največja potrata pri tvojem programu je da OpenMP zaradi uporabe shared naredi lock na dostop do celotnih tabel a in max. Tako v bistvu spremeniš svoj program v zaporeden saj različne niti čakajo ena na drugo da dobijo dostop do tabele. To pa ni potrebno saj dve različni niti nikoli ne pišeta v isto lokacijo v tabeli a ali v tabeli max. Niti so tako neodvisne saj ne posegajo med seboj v vhodne ali pa v izhodne podatke.
#pragma omp parallel for shared(a,max) private(tn)
uporabi
#pragma omp parallel for private(tn)
Največja potrata pri tvojem programu je da OpenMP zaradi uporabe shared naredi lock na dostop do celotnih tabel a in max. Tako v bistvu spremeniš svoj program v zaporeden saj različne niti čakajo ena na drugo da dobijo dostop do tabele. To pa ni potrebno saj dve različni niti nikoli ne pišeta v isto lokacijo v tabeli a ali v tabeli max. Niti so tako neodvisne saj ne posegajo med seboj v vhodne ali pa v izhodne podatke.
Zgodovina sprememb…
- spremenil: Rokm ()
Arto ::
Hvala za odgovor!
Ugotovil sem, da je bila glavna napaka, da metoda omp_get_thread_num porabi precej časa. Kolega mi je svetoval, naj popravim takole:
Zadeva je zdaj hitrejša (pohitritev je okrog 1.3x), Je pa hecno, da praktično nima veze, če dam pri for zanki shared(a,max) ali ne.
Ugotovil sem, da je bila glavna napaka, da metoda omp_get_thread_num porabi precej časa. Kolega mi je svetoval, naj popravim takole:
int max_num_p(int a_size, int a[]){ int i, tn, max[N_THREADS]; omp_set_num_threads(N_THREADS); #pragma omp parallel private(tn) { tn = omp_get_thread_num(); #pragma omp for for(i=0; i<a_size; i++){ if(max[tn]<a[i]) max[tn]=a[i]; } } return max_num(N_THREADS, max); }
Zadeva je zdaj hitrejša (pohitritev je okrog 1.3x), Je pa hecno, da praktično nima veze, če dam pri for zanki shared(a,max) ali ne.
Rokm ::
Čudno! Meni z odstranitvijo shared(max, a) deluje hitreje. Je pa res da poganjam to na linux mašini compajlano z mpicc, tako da mogoče se pri teki uporabijo kakšne optimizacije.
Očitno more biti nekaj takega saj če poskusim gcc -O3 tudi pri meni ni razlike med verzijo s shared ali brez.
Očitno more biti nekaj takega saj če poskusim gcc -O3 tudi pri meni ni razlike med verzijo s shared ali brez.
Arto ::
Jaz kompajlam v Visual Studio 2010. Verjetno je res kakšen hec pri optimizaciji pri samem kompilanju.
Gemm ::
Ko poganjam tale kos kode (s popravkom ki get_thread_num premakne ven iz zanke), opazim da mi v nobenem trenutku ne zabije več kot enega jedra - sumim da dela na neki točki lock na tabelo a, kot je Rokm namignil. Testirano na linuksih z GCC in LLVM.. to bi tudi mene zanimalo kaj se to dogaja, ker precej pogosto uporabljam OpenMP in bi se rad izognil tovrstnim presenečenjem.
Rokm ::
Čudno! Meni pri uporabi -O3 opcije za prevajanje teče vzporedna koda približno trikrat hitreje kot zaporedna (na računalniku z osmimi jedri). Se tudi opazi poraba procesarja, ki skoči na 800% procentov, če povečaš N.
Mogoče povečane porabe ne opaziš ker se sprememba zgodi prehitro?
Če poženeš program s time se ob uporabi večih niti zna zgoditi, da je user time večji kot real time.
Mogoče povečane porabe ne opaziš ker se sprememba zgodi prehitro?
Če poženeš program s time se ob uporabi večih niti zna zgoditi, da je user time večji kot real time.
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [Java - DN] Naključna številaOddelek: Šola | 1364 (893) | nyler |
» | Java passingOddelek: Programiranje | 3623 (3276) | mihibo5 |
» | c napaka .c:4:1: error: expected identifier or '(' before '{' tokenOddelek: Programiranje | 1944 (1517) | MrStein |
» | [C++] velikost matrikeOddelek: Programiranje | 1706 (1518) | Jean-Paul |
» | srand in program v Cju???Oddelek: Programiranje | 1592 (1462) | nuclear |