На этом шаге мы рассмотрим некоторые приемы, используемые для исключения неоднозначности вычислений.
Рассмотренный подход уменьшает эффект состязания потоков, но не гарантирует единственности решения при повторении вычислений. Для достижения однозначности необходимо использование дополнительных вычислительных схем.
Возможный и широко применяемый в практике расчетов способ состоит в разделении места хранения результатов вычислений на предыдущей и текущей итерациях метода сеток. Схема такого подхода может быть представлена в следующем общем виде:
omp_lock_t dmax_lock; omp_init_lock(dmax_lock); do { dmax = 0; // максимальное изменение значений u #pragma omp parallel for shared(u,n,dmax) \ private(i,temp,d,dm) for ( i=1; i<N+1; i++ ) { dm = 0; for ( j=1; j<N+1; j++ ) { temp = u[i][j]; un[i][j] = 0.25*(u[i-1][j]+u[i+1][j]+ u[i][j-1]+u[i][j+1]-h*h*f[i][j]); d = fabs(temp-un[i][j]) if ( dm < d ) dm = d; } omp_set_lock(dmax_lock); if ( dmax < dm ) dmax = dm; omp_unset_lock(dmax_lock); } } // конец параллельной области for ( i=1; i<N+1; i++ ) // обновление данных for ( j=1; j<N+1; j++ ) u[i][j] = un[i][j]; } while ( dmax > eps );
Как следует из приведенного алгоритма, результаты предыдущей итерации запоминаются в массиве u, новые вычисленные значения запоминаются в дополнительном массиве un. Как результат, независимо от порядка выполнения вычислений для проведения расчетов всегда используются значения величин uij от предыдущей итерации метода. Такая схема реализации сеточных алгоритмов обычно именуется методом Гаусса-Якоби. Этот метод гарантирует однозначность результатов независимо от способа распараллеливания, но требует использования большого дополнительного объема памяти и обладает меньшей (по сравнению с алгоритмом Гаусса-Зейделя) скоростью сходимости.
Иной возможный подход для устранения взаимозависимости параллельных потоков состоит в применении схемы чередования обработки четных и нечетных строк, когда выполнение итерации метода сеток подразделяется на два последовательных этапа, на первом из которых обрабатываются строки только с четными номерами, а затем на втором этапе - строки с нечетными номерами. Данная схема может быть обобщена на применение одновременно и к строкам, и к столбцам (блочное разбиение) области расчетов.
Рассмотренная схема чередования строк не требует по сравнению с методом Гаусса-Якоби какой-либо дополнительной памяти и обеспечивает однозначность решения при многократных запусках программы. Но следует заметить, что оба рассмотренных в данном пункте подхода могут получать результаты, не совпадающие с решением задачи Дирихле, найденном при помощи последовательного алгоритма. Кроме того, эти вычислительные схемы имеют меньшую область и худшую скорость сходимости, чем исходный вариант метода Гаусса-Зейделя.
На следующем шаге мы рассмотрим волновые схемы параллельных вычислений.