martes, 1 de septiembre de 2009

RESHAPE es ineficiente

Fortran es un lenguaje pensado para escribir en el ordenador fórmulas matemáticas, o más en general, cálculos científicos. Y es muy bueno trabajando con matrices multidimensionales: se puede escribir


real(4) :: a(64,64,64)
real(4) :: b(10,10,10)

[...]

b=a(1:10,1:10,1:10)


y así, sin necesidad de bucles, copiamos un trozo de una matriz en la otra. O también podemos, para rellenar de datos una matriz:


real(4) :: a(1:64,1:64,1:64)
integer :: i,j,k

a=RESHAPE( (/ ( (/ ( (/ ( REAL((i-1+(64/2))/64)+1.0 ,k=1,64) /) ,j=1,64) /) ,i=1,64) /) , (/64,64,64/) )


para rellenar un cubo de datos de 64*64*64 con los valores 1 y 2. Esto es lo mismo que


real(4) :: a(1:64,1:64,1:64)
integer :: i,j,k

do k=1,64
do j=1,64
do i=1,64
a(i,j,k)=REAL((i-1+(64/2))/64)+1.0
end do
end do
end do


aunque la filosofía no es la misma. En el primer caso, creamos una ristra de 64*64*64 valores que después adaptamos a un cubo de lado 64. En el segundo caso calculamos los valores uno por uno y los vamos colocando en sus lugares de memoria. El segundo código parece más ineficiente, y puede que el compilador no lo sepa optimizar bien... pero el primero es el realmente ineficiente: compilarlo puede tardar muchísimo más, incluso hacerse eterno con valores mayores, mientras que el segundo se compila en un instante y se ejecuta en poco tiempo.

Recordemos, pues, que salvo en determinadas ocasiones, explícito es mejor que implícito, por mucho que les duela a los fortranistas de toda la vida.

No hay comentarios: