Fortran :динамические массивы против автоматического массива Избегание выделения памяти

При профилировании одного из наших кодов на Фортране есть две подпрограммы, которые занимают большую часть вычислительного времени (22,1% и 17,2% ). В каждой подпрограмме ~5% времени тратится на выделение и освобождение памяти. Эти подпрограммы выглядят как

MODULE foo

CONTAINS

SUBROUTINE bar(... )
...
IMPLICIT NONE
...
REAL, ALLOCATABLE, DIMENSION(:,:) :: work
...
ALLOCATE (work(size1,size2))
...
DEALLOCATE (work)
END SUBROUTINE bar
...
END MODULE foo

Эти подпрограммы вызываются порядка ~4000 -5000 раз в моем тесте, поэтому я хотел бы избавиться от ALLOCATE и DEALLOCATE. Изменение их на автоматические массивы изменяет вывод профилировщика на.

MODULE foo

CONTAINS

SUBROUTINE bar(... )
...
IMPLICIT NONE
...
REAL, DIMENSION(size1,size2) :: work
...
END SUBROUTINE bar
...
END MODULE foo

Изменяет результирующий профиль на

Running Time        Symbol Name
20955.0ms  17.0%    __totzsp_mod_MOD_totzsps
    7.0ms   0.0%        malloc
    5.0ms   0.0%        free
    2.0ms   0.0%        user_trap

16192.0ms  13.2%    __tomnsp_mod_MOD_tomnsps
   20.0ms   0.0%        free
    3.0ms   0.0%        malloc
    1.0ms   0.0%        szone_size_try_large

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

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

работа _массив.f

MODULE work_array
IMPLICIT NONE

REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: work

END MODULE work_array

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

MODULE foo

CONTAINS

SUBROUTINE bar(... )
...
USE work_array
IMPLICIT NONE
...
END SUBROUTINE bar
...
END MODULE foo

Однако, когда я запускаю код, профиль ухудшается.

Running Time        Symbol Name
30584.0ms  21.6%    __totzsp_mod_MOD_totzsps
 3494.0ms   2.4%        free
 3143.0ms   2.2%        malloc
   27.0ms   0.0%        DYLD-STUB$$malloc_zone_malloc
   19.0ms   0.0%        szone_free_definite_size
    6.0ms   0.0%        malloc_zone_malloc

24325.0ms  17.1%    __tomnsp_mod_MOD_tomnsps
 2937.0ms   2.0%        free
 2456.0ms   1.7%        malloc
   23.0ms   0.0%        DYLD-STUB$$malloc_zone_malloc
    3.0ms   0.0%        szone_free_definite_size

Откуда берутся эти дополнительные malloc и free? Как я могу настроить это так, чтобы я выделял эти массивы один раз?

9
задан user1139069 26 June 2012 в 07:46
поделиться