Masz chyba źle podomykane klamry. Zamknij pierwszą klamrę przed drugim #pragma
.
A to nie powinno być w jednej? Myślałem, że trzeba zrobić w jednej i dodać potem sekcje zabezpieczające: critical lub reduction. Bo jak mam to w dwóch pragma to to wtedy dwa razy uruchamiają się wątki ?? Albo ja to źle to ogarniam?
W obecnym kodzie linijka:
#pragma omp parallel private(i,j)
dokonuje podziału wątku głównego na pewną liczbę wątków. Wszystko co dzieje się od klamry pomiędzy liniami 6 i 23 dzieje się równolegle. Czyli nic nie zyskujesz, bo praca nie jest dzielona, tylko wykonywana wielokrotnie.
Linia:
#pragma omp parallel for schedule(static,2) private(i,j,k)
Dokonuje ponownego podziału każdego wątku na 2 i podzielenia pracy w następującej po niej pętli for.
Pamiętaj, że:
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
jest równoważne
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
zwróć uwagę na brak parallel
w drugiej sekcji #pragma
.
Ja zrobiłbym pierwszą sekcję, w której zeruję macierz C
#pragma omp parallel for private(i,j)
{
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
{
C[i][j]=0;
}
}
To powinno rozdzielić zewnętrzną iteracje zewnętrznej pętli for pomiędzy wątkami, i wydaje mi się, że sekcje krytyczne nie będą potrzebne, bo każdy wątek będzie próbował zapisać tylko w komórkach o swoim indeksie i
.
Podobnie tu:
#pragma omp parallel for schedule(static,2) private(i,j,k)
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
for(k=0; k<c1; ++k)
{
C[i][j]+=A[i][k]*B[k][j];
}
Wydaje mi się, że też obejdzie się bez sekcji krytycznych, bo każdy wątek wpisuje do swoich komórek. Usunąłem jedną klamrę, dzięki temu wypiszA
wykona się tylko raz.
Tak w ogóle to nie musiałbyś deklarować prywatności i,j,k
gdybyś deklarował je wewnątrz for.