Profilowanie jednego z naszych kodów fortranowych obejmuje dwa podprogramy, które zajmują większość czasu obliczeniowego (22,1% i 17,2%). W każdej z procedur około 5% czasu zajmuje przydzielanie i zwalnianie pamięci. Procedury te wyglądająFortran: dynamiczne tablice vs. automatyczna tablica Unikanie alokacji pamięci
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
IMPLICIT NONE
...
REAL, ALLOCATABLE, DIMENSION(:,:) :: work
...
ALLOCATE (work(size1,size2))
...
DEALLOCATE (work)
END SUBROUTINE bar
...
END MODULE foo
te podprogramy sprawdzony rzędu ~ 4000-5000 razy w moim znakiem ławce więc chciałbym się pozbyć alokuje i zwalnianie. Zmiana tych na automatyczne tablice zmienia profil na wyjściowy profiler.
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
IMPLICIT NONE
...
REAL, DIMENSION(size1,size2) :: work
...
END SUBROUTINE bar
...
END MODULE foo
Zmienia wynikowy profil do
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
I wygląda gfortran przeznacza je na stosie, a nie, że sterty ale jestem zaniepokojony, kiedy się dzieje, gdy te tablice stają się zbyt duże.
Drugie podejście, które podejmuję, to przydzielenie i zwolnienie tych tablic jeden raz.
work_array.f
MODULE work_array
IMPLICIT NONE
REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: work
END MODULE work_array
mogę przeznaczyć je raz w innej części kodu. Teraz mój podprogram wygląda jak
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
USE work_array
IMPLICIT NONE
...
END SUBROUTINE bar
...
END MODULE foo
Jednak po uruchomieniu kodu profil staje się coraz gorszy.
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
Skąd się biorą te dodatkowe mallokso i zwalnia? Jak mogę to ustawić, aby przydzielić te tablice jeden raz?
Tablice sterty w Fortranie są przydzielane i zwalniane w każdym wywołaniu funkcji przez niejawne wywołania 'malloc' /' free'.Nie różnią się one od tablic "ALLOCATABLE" w tym zakresie. –
Nie spodziewałbym się, że tak się stanie z programem ifort. Używam twojego drugiego podejścia przez cały czas, tj. Mając wstępnie przydzielony bufor, którego używam wielokrotnie, bez zwolnienia i ponownego przydzielenia. – bdforbes
Nie jest możliwe, że profil pogorszy się po przydzieleniu jednego z góry ... Czy wiesz, dlaczego? – Lupocci