Я застрял при распараллеливании следующего кода:
double[][] a, b, c;
double d;
double[] e;
for (int i = 1; i < x; i++) {
double f = 0.0;
for (int j = 0; j < y; j++) {
double a1 = a[i-1][j];
double a2 = a[i][j];
double a3 = a1 * a2;
d -= a3;
c[i][j] = c[i - 1][j] + a3;
f += c[i][j] * a3;
}
e[i] = d + f;
for (int j = 0; j < y; j++) {
a[i][j] = e[i] * b[i][j]
}
}
Второй внутренний цикл зависит от первого (из-за e[i]
), поэтому они должны выполняться последовательно, но внутри каждого из них вычисления могут быть распараллелены на y
.
Проблема в том, что они читают и пишут по внешним переменным. Запись может быть распараллелена (концептуально), потому что каждый внутренний цикл объединяет свои частичные результаты с глобальными переменными.
x
имеет порядок 10000 и y
250. Обработка внутренних циклов в этом примере упрощена, но на самом деле требует больших вычислительных ресурсов.
Вопрос здесь в том, как распараллелить циклы, которые читают и пишут внешние переменные?
Следующая попытка не компилируется из-за d
и f
:
double[][] a, b, c;
double d;
double[] e;
for (int i = 1; i < x; i++) {
double f = 0.0;
IntStream.range(0, y).parallel().forEach(j -> {
double a1 = a[i-1][j];
double a2 = a[i][j];
double a3 = a1 * a2;
d -= a3;
c[i][j] = c[i - 1][j] + a3;
f += c[i][j] * a3;
});
e[i] = d + f;
IntStream.range(0, y).parallel().forEach(j -> {
a[i][j] = e[i] * b[i][j];
});
}