Как я могу убедиться, что моя конструкция Fortran FORALL распараллеливается? - PullRequest
5 голосов
/ 06 сентября 2010

Мне дали 2D матрицу, представляющую температурные точки на поверхности металлической пластины. Края матрицы (пластины) удерживаются постоянными при 20 градусах Цельсия, и в одной предварительно определенной точке имеется источник постоянного тепла в 100 градусов Цельсия. Все остальные точки сетки изначально установлены на 50 градусов Цельсия.

Моя цель состоит в том, чтобы взять все внутренние точки сетки и вычислить ее установившуюся температуру путем итеративного усреднения по окружающим четырем точкам сетки (i + 1, i-1, j + 1, j-1), пока я не достигну сходимости ( изменение менее 0,02 градуса C между итерациями).

Насколько я знаю, порядок, в котором я перебираю точки сетки, не имеет значения.

Для меня это звучит как прекрасное время для вызова конструкции Fortran FORALL и изучения радостей распараллеливания.

Как я могу убедиться, что код действительно распараллеливается?

Например, я могу скомпилировать это на своем одноядерном PowerBook G4, и я не ожидаю улучшения скорости из-за распараллеливания. Но если я скомпилирую на двухъядерном AMD Opteron, я предполагаю, что конструкция FORALL может быть использована.

В качестве альтернативы, есть ли способ измерения эффективного распараллеливания программы?

Обновление

В ответ на вопрос М.С.Б. это с gfortran версии 4.4.0. Gfortran поддерживает автоматическую многопоточность?

Примечательно, что конструкция FORALL устарела, как я полагаю, благодаря автоматической векторизации.

Возможно, это лучше всего для отдельного вопроса, но как работает авто-векторизация? Может ли компилятор обнаружить, что в цикле используются только чистые функции или подпрограммы?

Ответы [ 3 ]

7 голосов
/ 21 сентября 2010

FORALL является конструкцией присваивания, а не циклической конструкцией.Семантика FORALL гласит, что выражение в правой части (RHS) каждого присваивания в пределах FORALL полностью оценивается перед его назначением в левую часть (LHS).Это должно быть сделано независимо от того, насколько сложны операции на RHS, включая случаи, когда RHS и LHS накладываются друг на друга.

Большинство компиляторов используют оптимизацию FORALL, потому что это трудно оптимизировать, и потому что это не так.обычно используется.Самая простая реализация - просто выделить временное для RHS, оценить выражение и сохранить его во временном, а затем скопировать результат в LHS.Выделение и освобождение этого временного файла, вероятно, заставит ваш код работать довольно медленно.Компилятору очень сложно автоматически определить, когда RHS может быть оценена без временной обработки;большинство компиляторов не делают никаких попыток сделать это.Вложенные циклы DO оказываются намного проще для анализа и оптимизации.

С некоторыми компиляторами вы можете распараллеливать оценку RHS, заключая в FORALL директиву «рабочая доля» OpenMP и компилируя с любыми флагаминеобходимы для включения OpenMP, например:

!$omp parallel workshare
FORALL (i=,j=,...)
    <assignment>
END FORALL
!$omp end parallel

gfortran -fopenmp blah.f90 -o blah

Обратите внимание, что совместимая реализация OpenMP (включая как минимум более старые версии gfortran) не являетсятребуется оценить RHS параллельно;для реализации допустимо оценивать RHS, как если бы оно было включено в OpenMP «единую» директиву.Также обратите внимание, что «рабочая доля», скорее всего, не устранит временное выделение RHS.Это имело место, например, со старой версией компилятора IBM Fortran в Mac OS X.

6 голосов
/ 20 сентября 2010

Если вы используете Intel Fortran Compiler, вы можете использовать переключатель командной строки, чтобы включить / увеличить уровень детализации компилятора для распараллеливания / векторизации.Таким образом, во время компиляции / компоновки вам будет показано что-то вроде:

FORALL loop at line X in file Y has been vectorized

Я признаю, что прошло несколько лет с тех пор, как я в последний раз использовал его, поэтому сообщение компилятора могло бы выглядеть совсем иначе,но это основная идея.

3 голосов
/ 06 сентября 2010

Лучший способ - измерить время вычислений.Попробуйте с параллельным кодом и без него.Если время на часах уменьшается, значит, ваш параллельный код работает.Внутренний системный блок Фортрана, вызываемый до и после блока кода, даст вам время часов.Встроенный cpu_time даст вам время процессора, которое может увеличиться, когда код запускается многопоточным из-за накладных расходов.

Знание о том, что FORALL не так полезен, как предполагалось при введении в язык -что это скорее конструкция инициализации.Компиляторы одинаково хорошо умеют оптимизировать регулярные циклы.

Компиляторы Fortran различаются по своим возможностям для реализации истинной параллельной обработки без явного указания, например, с OpenMP или MPI.Какой компилятор вы используете?

Чтобы получить автоматическую многопоточность, я использовал ifort.Вручную я использовал OpenMP.С обоими из них вы можете скомпилировать вашу программу с параллелизацией и без нее и измерить разницу.

...