OpenMP распараллелить для создания производительности

Первый метод (распараллелить внутренний цикл):

for(j=0; j<LATTICE_VW; ++j) {
x = j*DX + LATTICE_W;
#pragma omp parallel for ordered private(y, prob)
for(i=0; i<LATTICE_VH; ++i) {
y = i*DY + LATTICE_S;
prob = psi[i][j].norm();

#pragma omp ordered
out << x << " " << y << " " << prob << endl;
}
}

Второй метод (распараллелить внешний цикл):

#pragma omp parallel for ordered private(x, y, prob)
for(j=0; j<LATTICE_VW; ++j) {
x = j*DX + LATTICE_W;
for(i=0; i<LATTICE_VH; ++i) {
y = i*DY + LATTICE_S;
prob = psi[i][j].norm();

#pragma omp ordered
out << x << " " << y << " " << prob << endl;
}
}

Третий метод (распараллелить свернутые циклы)

#pragma omp parallel for collapse(2) ordered private(x, y, prob)
for(j=0; j<LATTICE_VW; ++j) {
for(i=0; i<LATTICE_VH; ++i) {
x = j*DX + LATTICE_W;
y = i*DY + LATTICE_S;
prob = psi[i][j].norm();

#pragma omp ordered
out << x << " " << y << " " << prob << endl;
}
}

Если бы я собирался угадать, я бы сказал, что метод 3 должен быть самым быстрым.

Однако способ 1 является самым быстрым, в то время как второй и третий занимают примерно одинаковое количество времени, как если бы не было распараллеливания. Почему это происходит?

0

Решение

Посмотри с этим:

for(int x = 0; x < 4; ++x)
#pragma omp parallel for ordered
for(int y = 0; y < 4; ++y)
#pragma omp ordered
cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

у тебя есть:

0,0 (by thread 0)
0,1 (by thread 1)
0,2 (by thread 2)
0,3 (by thread 3)
1,0 (by thread 0)
1,1 (by thread 1)
1,2 (by thread 2)
1,3 (by thread 3)

Каждый поток просто должен подождать cout всю работу можно выполнить параллельно.
Но с:

#pragma omp parallel for ordered
for(int x = 0; x < 4; ++x)
for(int y = 0; y < 4; ++y)
#pragma omp ordered
cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

а также

#pragma omp parallel for collapse(2) ordered
for(int x = 0; x < 4; ++x)
for(int y = 0; y < 4; ++y)
#pragma omp ordered
cout << x << ',' << y << " (by thread " << omp_get_thread_num() << ')' << endl;

ситуации это:

0,0 (by thread 0)
0,1 (by thread 0)
0,2 (by thread 0)
0,3 (by thread 0)
1,0 (by thread 1)
1,1 (by thread 1)
1,2 (by thread 1)
1,3 (by thread 1)
2,0 (by thread 2)
2,1 (by thread 2)
2,2 (by thread 2)
2,3 (by thread 2)
3,0 (by thread 3)
3,1 (by thread 3)
3,2 (by thread 3)
3,3 (by thread 3)

Так thread 1 должен ждать thread 0 закончить всю свою работу, прежде чем он сможет cout в первый раз, и почти ничего нельзя сделать параллельно.

Попробуйте добавить schedule(static,1) до коллапс-версии, и она должна работать по крайней мере так же хорошо, как и первая версия.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]