выполнение матричных операций с фортраном - PullRequest
0 голосов
/ 17 мая 2011

Мне нужно где-то использовать Fortran вместо C, и я очень плохо знаком с Fortran. Я пытаюсь сделать некоторые большие вычисления, но это довольно медленно по сравнению с C (возможно, 10x или больше, и я использую компиляторы Intel для обоих). Я думаю, причина в том, что Fortran хранит матрицу в основном формате столбца, и я пытаюсь выполнять такие операции, как sum (matrix (i, j, :)), потому что это главный столбец, возможно, он использует кэш очень неэффективно (вероятно, нет). используя вообще). Однако я не уверен, является ли это реальной причиной (так как я знаю так мало о Фортране). Вопрос в том, что в Фортране принято выполнять операции над векторами столбцов вместо векторов строк?

(Кстати: я проверил скорость Fortran, уже используя библиотеки Intel LAPACK, и она довольно быстрая, поэтому она не связана с какими-либо проблемами компилятора или сборки.)

Спасибо.

Мета

Ответы [ 2 ]

4 голосов
/ 17 мая 2011

Поскольку, как вы пишете, Fortran является основным столбцом с первым индексом, изменяющимся быстрее всего в макете памяти, поэтому sum (matrix (i, j, :)) вызывает суммирование несмежных местоположений. Если это действительно является причиной более медленной работы, то вы можете переопределить матрицу, чтобы иметь другой порядок измерений, чтобы текущее 3-е измерение было 1-м. Да, если это ваши основные вычисления, переставьте матрицу, чтобы суммирование стало операцией столбца. Явное зацикливание должно выполняться так же быстро, как и ранние индексы, как описано в @PaulR. Если вы ранее думали об оптимальном порядке индекса для C и переходите на Fortran, это один из аспектов, который может потребоваться изменить. Но хотя это теоретически верно, я сомневаюсь, что это действительно так важно на практике, если, возможно, массив не огромен. (В худшем случае часть массива находится в оперативной памяти, а часть - в разделе подкачки на диске!). Первое правило, касающееся проблем со скоростью во время выполнения, - не угадывать ... измерять. Обычно это алгоритм.

4 голосов
/ 17 мая 2011

Попробуйте изменить порядок ваших циклов при выполнении матричных операций, например, если у вас есть что-то подобное в C:

for (i = 0; i < M; ++i) // for each row
{
    for (j = 0; j < N; ++j) // for each col
    {
        // matrix operations on e.g. A[i][j]
    }
}

затем в Фортране вы хотите, чтобы цикл j (столбец) использовался как внешний цикл, а цикл i (строка) - как внутренний цикл.

Альтернативный подход, который позволяет достичь того же, состоит в том, чтобы сохранить циклы такими, какие они есть, но изменить определение массива, например, если в С это A[x][y][z][t], то в ФОРТРАНЕ сделайте его A[t][z][y][x], предполагая, что t - самый быстро меняющийся индекс цикла, а x - самый медленный.

...