Al perfilar uno de nuestros códigos fortran, hay dos subrutinas que ocupan la mayor parte del tiempo computacional (22.1% y 17.2%). En cada rutina, ~ 5% del tiempo se gasta en asignar y liberar memoria. Estas rutinas se ven comoFortran: matrices dinámicas frente a matriz automática Evitar la asignación de memoria
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
IMPLICIT NONE
...
REAL, ALLOCATABLE, DIMENSION(:,:) :: work
...
ALLOCATE (work(size1,size2))
...
DEALLOCATE (work)
END SUBROUTINE bar
...
END MODULE foo
estas subrutinas llaman a ellas del orden de ~ 4000-5000 veces en mi punto de referencia por lo que me gustaría deshacerse de asignar y DEALLOCATE. Cambiar estos a arreglos automáticos cambia a la salida del generador de perfiles.
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
IMPLICIT NONE
...
REAL, DIMENSION(size1,size2) :: work
...
END SUBROUTINE bar
...
END MODULE foo
Cambia el perfil resultante a
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
Me parece que gfortran es la asignación de éstos en la pila y no ese montón, pero me preocupa cuando sucede cuando estas matrices se vuelven demasiado grandes.
El segundo enfoque que estoy tomando es asignar y desasignar estas matrices una vez.
work_array.f
MODULE work_array
IMPLICIT NONE
REAL(rprec), ALLOCATABLE, DIMENSION(:,:) :: work
END MODULE work_array
asigno estos una vez en una parte diferente del código. Ahora mi subrutina se parece a
MODULE foo
CONTAINS
SUBROUTINE bar(...)
...
USE work_array
IMPLICIT NONE
...
END SUBROUTINE bar
...
END MODULE foo
Sin embargo, cuando ejecuto el código ahora el perfil empeora.
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
¿De dónde vienen estos extra mallocs y libres? ¿Cómo puedo configurar esto para que yo asigne estas matrices una vez?
Las matrices de montón en Fortran se asignan y desasignan en cada llamada de función mediante llamadas 'malloc' /' free' implícitas.No son diferentes de las matrices 'ALLOCATABLE' a este respecto. –
No esperaría que esto suceda con ifort. Uso su segundo enfoque todo el tiempo, es decir, tener un búfer preasignado que utilizo muchas veces sin desasignar ni reasignar. – bdforbes
No es posible que el perfil empeore cuando asigna uno de antemano ... ¿descubrió por qué? – Lupocci