Я пишу программу на Фортране. В программе реализованы некоторые численные методы. Скорость программы очень важна. Я решил избавиться от динамических массивов (ускоряет ли это программу?) И столкнулся со следующей проблемой. У меня есть трехмерные массивы (элементы NXxNYxNZ = MAX), где я знаю MAX, но я не знаю соотношение NX / NY / NZ. Это может быть так: 1x1xNZ или как это 2xNYx1 и т. Д. Решение, которое я вижу — использовать указатели. Упрощенный 2D-случай:
program ptrtest
parameter ( MAX = 50 ) ! I know this number on compile time.
integer :: NX,NY ! I will find this numbers on run time.
real, target :: a(MAX) ! Static Array
real, pointer :: b(:,:)
a = 5
read(*,*) NX, NY ! I get NX, NY (NX*NY == MAX)
b (1:NX, 1:NY) => a ! I can use b(:,:) <- this is my goal.
end program ptrtest
Этот пример работает, но я боюсь, что такое обновление замедлит работу реальной программы, в которой я использую даже 5d массивы. Является ли это возможным?
Вы не показываете достаточно программы, чтобы по-настоящему комментировать (Вы работаете с a и b одновременно? Вы сразу передаете b в подпрограмму?), Но в целом производительность будет хуже при работе с переменными, которые имеют TARGET или POINTER, потому что некоторые оптимизации могут быть предотвращены. Это будет зависеть от специфики, но выделение выделяемого массива размера (nx, ny) один раз вряд ли будет таким значительным падением производительности по сравнению с чем-то вроде оператора READ, который заполняет nx и ny. — person Vasiliy schedule 18.12.2014
Если вам нужен массив с размерами, определяемыми во время выполнения, я рекомендую использовать выделяемый массив, а не массив указателей, если вам также не нужна дополнительная функция указателя. размещаемые объекты безопаснее. Кроме того, лучше всего решить вашу проблему, а затем определить медленные части, а не гадать с самого начала. Микрооптимизации редко имеют большое значение. Выбор эффективного алгоритма важен. — person Vasiliy schedule 18.12.2014
FWIW Я согласен с другими комментаторами. Но если вы знаете MAX
во время компиляции, но не знаете, до времени выполнения _2 _, _ 3_ и nz
, вы всегда можете использовать проверенный (для которого понимается «старомодный») подход использования одномерного массива ( из MAX
элементов) и арифметические операции с собственным индексом. Если вы рассматриваете этот подход, внимательно изучите наблюдения @ M.S.B. по оптимизации. — person Vasiliy schedule 18.12.2014
Вы говорите, что скорость программы важна, поэтому старый стиль Fortran даст вам лучшее:
MAX
NZ
. Это позволит избежать косвенного обращения к указателю, что приведет к потере производительности (в отличие от C, стандарт Fortran предполагает, что аргументы массива подпрограммы не перекрываются, см. этот пост).Например:
Если производительность действительно имеет значение, вот еще несколько полезных приемов:
!DIR$ ATTRIBUTES ALIGN : 32
!DIR$ VECTOR ALIGNED
Например:
Редактировать
Этот трюк старого стиля Fortran позволяет избежать наложения имен указателей.
Ссылки на псевдонимы указателей:
так что старый стиль Fortran даст вам лучшее Покажите нам числа; без данных этот «ответ» — мнение. — person Vasiliy; 18.12.2014
Это не мнение. Посмотрите на параметр -fno-alias компиляторов C, чтобы получить дополнительные объяснения. Как я уже сказал: (в отличие от C, стандарт Fortran предполагает, что аргументы массива подпрограмм не перекрываются). Псевдонимы указателей — это хорошо известная проблема для компиляторов, и она отсутствовала в Фортране до того, как они представили указатели. Видеть — person Vasiliy; 18.12.2014
Я тоже хотел бы увидеть реальные цифры. — person Vasiliy; 19.12.2014