Mam dwie wersje kodu, które dają równoważne wyniki, gdy próbuję zrównoleglić tylko wewnętrzną pętlę zagnieżdżonej pętli for
. Nie uzyskuję zbyt dużej prędkości, ale nie spodziewałem się 1-do-1, ponieważ próbuję tylko zrównoleglić wewnętrzną pętlę.jak uniknąć narzutów OpenMP w zagnieżdżonych pętlach
Moje główne pytanie brzmi: dlaczego te dwie wersje mają podobne środowiska wykonawcze? Czy druga wersja nie wyświetla wątków tylko raz i nie pozwala na narzut uruchamiania nowych wątków w każdej iteracji ponad i
, tak jak w pierwszej wersji?
Pierwsza wersja kodu uruchamia się nici w każdej iteracji pętli zewnętrznej, jak to:
for(i=0; i<2000000; i++){
sum = 0;
#pragma omp parallel for private(j) reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
final += sum;
}
printf("final=%d\n",final/2000000);
Z tego wyjścia i wykonywania:
OMP_NUM_THREADS = 1
final=1000
real 0m5.847s
user 0m5.628s
sys 0m0.212s
OMP_NUM_THREADS = 4
final=1000
real 0m4.017s
user 0m15.612s
sys 0m0.336s
Druga wersja kodu rozpoczyna wątki raz przed zewnętrznej pętli i parallelizes wewnętrznej pętli tak (?):
#pragma omp parallel private(i,j)
for(i=0; i<2000000; i++){
sum = 0;
#pragma omp barrier
#pragma omp for reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
#pragma omp single
final += sum;
}
printf("final=%d\n",final/2000000);
Z tego wyjścia i wykonywania:
OMP_NUM_THREADS = 1
final=1000
real 0m5.476s
user 0m4.964s
sys 0m0.504s
OMP_NUM_THREADS = 4
final=1000
real 0m4.347s
user 0m15.984s
sys 0m1.204s
dlaczego czy druga wersja jest znacznie szybsza od pierwszej? Czy to nie pozwala na uruchamianie wątków w każdej iteracji pętli lub czy robię coś nie tak?
Prawdopodobnie dlatego, że Twoja implementacja OpenMP skutecznie przetłumaczyła twoją pierwszą wersję na twoją drugą wersję. Większość implementacji jest wystarczająco inteligentna, aby utrzymać twoje wątki przy życiu, jeśli widzi, że są ciągle tworzone wewnątrz zewnętrznej pętli. – NoseKnowsAll
Twoja druga wersja jest lepsza nawet w przypadku pul wątków, zobacz [tutaj] (https://stackoverflow.com/questions/71/openmp-nested-for-loop-becomes-faster-when-having-parallel-before-outer- loop/31382775 # 31382775). –
Och, jestem zaskoczony, że twoja druga wersja jest wolniejsza. Czy skompilowałeś z optymalizacją? Próbowałem twój kod z optymalizacją i bez OpenMP wewnętrzna pętla jest optymalizowana do 1000, ale z OpenMP nie jest. Prawdopodobnie nie skompilowałeś się z optymalizacją. –