Loading [MathJax]/extensions/TeX/AMSsymbols.js

PESTAÑAS

domingo, 7 de abril de 2013

Consejos para programación avanzada en FORTRAN

Hola a todos

En este artículo voy a hablar sobre programación avanzada en FORTRAN. Cuando me refiero a programación "avanzada" en FORTRAN quiero remarcar implícitamente que las estructuras sintácticas utilizadas para realizar nuestro programa no van a ser aquellas que permitan ejecutar correctamente el programa, sino aquellas que pueden ofrecer grandes ventajas en cuanto a TIEMPO DE COMPUTACIÓN Y ALMACENAMIENTO EN MEMORIA.

Una estructura de computación avanzada es extremadamente útil cuando se necesita elaborar un programa que por sus características requiere de un esfuerzo computacional muy elevado. Ejemplos clásicos de este tipo de programas pueden ser los programas CFD (donde los solvers utilizados requieren una malla de puntos muy extensa para llevar a cabo la computación de la ecuación a resolver en el dominio estudiado) o programas que manipulen listas o matrices de datos MUY grandes.

Dejando a un lado el caso de que seas un experto programador (en cuyo caso lo que voy a decir en este artículo seguramente ya lo sabes puesto que de facto yo no soy tal), a la hora de computar un programa no siempre conviene diseñar EL MEJOR PROGRAMA, sino aquel programa que te de lo que necesitas en el menor tiempo posible DESDE QUE COMIENZAS A DISEÑARLO HASTA QUE OBTIENES LA RESPUESTA: de nada sirve elaborar un programa extremadamente eficiente que ahorra un 12% tu tiempo de computación si has empleado un esfuerzo en depurarlo y modificarlo al diseñarlo que sobrepasa con creces dicha cantidad de tiempo.

A continuación anotaré una serie de consejos en cuanto al manejo de FORTRAN buscando una estructura avanzada de programación:

1 - Conseguir elaborar tu programa intentando optimizar estos requisitos es una tarea hartamente complicada si no conoces casi a fondo las estructuras sintácticas que permite FORTRAN y las funciones intrínsecas que tiene implementadas. Échale un vistazo a las funciones intrínsecas que tiene implementado el programa y siempre que puedas utilízalas en vez de hacerte unas propias.

2 - Evita el uso de bucles DO siempre que puedas, sustituyéndolas por funciones intrínsecas. Por ejemplo en vez de recorrer una matriz elemento a elemento y realizar una operación específica, utiliza notación matricial que afecta simultáneamente a todos los elementos de la misma y es mucho más rápida.
Ejemplo: A = A +5, donde A es una matriz de tamaño M x N.

3 - Si quieres filtrar ciertos elementos de la matriz que te interesan y que son fácilmente distinguibles del resto (por ejemplo, elementos menores que 0 o que cumplan algún requisito lógico), la declaración WHERE te permite seleccionarlos instantáneamente mucho más rápidamente.

4 - FORTRAN odia los mapeados no lineales de elementos, prefiriendo seleccionar datos de forma lineal. Ejemplo: Si b1 = [1 3 8] y b2 = [2 4 6] son dos vectores con las posiciones de ciertos elementos dentro de otro vector más grande, entonces FORTRAN tarda sensiblemente más en acceder a A(b1) que a A(b2), puesto que el acceso a b2 se puede introducir en notación intrínseca de FORTRAN como A(2:6:2).

5 - Utiliza los punteros. Para los que no saben que es esto (yo lo desconocía hasta hace poco), un puntero es un objeto que no tiene una forma predefinida, esto es, es un objeto que puede tomar una dimensión variable dentro de su clase. Lo que quiero decir es que un puntero es un "alias" del objeto al que apunta, de tal forma que cuando hago referencia al puntero estoy accediendo en memoria física al objeto que se le ha asignado. Ejemplo: si se apunta con un puntero llamado Punt a un array  a1=[1 0 25 0 0]

Punt => a1

Entonces si se referencia Punt(3), entonces FORTRAN toma el valor 25. Pero a continuación se puede reasignar Punt a otro vector, b1=[2 3 4 5 6 7 8 9 0]. Ahora, Punt(3) = 4.  Como se puede ver, los punteros son extremadamente eficientes cuando se realizan actualizaciones de matrices grandes a partir de datos del paso anterior, ya que estos me permiten en cada paso calcular el nuevo valor de mi matriz a partir de los datos anteriores y asignárselo al puntero (lo que cambio es la dirección en memoria) en vez de borrar la matriz del paso anterior y volver a copiarla de la ya calculada en el paso actual.

6 - Graba en tu fichero de datos sólo los datos que necesites. Parece un consejo estúpido, pero cuando se hacen las cosas por inercia se tienden a cometer fallos de bulto. Por ejemplo, si estoy manipulando una matriz 8000 x 8000, pero mi información realmente está en unos cuantos puntos de la misma, en vez de grabar la matriz entera, copia sólo los elementos que se necesiten y su posición en la matriz (si es relevante).
Eso te evitará generar ficheros extremadamente pesados cuando hablamos de matrices de datos grandes.

7 - Evita la salida de datos por pantalla. Si el ordenador tiene que escribir por pantalla la iteración en la que esta a cada instante y datos de la simulación, es tiempo que esta empleando en ofrecer información que quizá sea irrelevante una vez el programa ya funciona. Reduce la salida por pantalla hasta dejar sólo lo imprescindible.

8 - El uso de variables dinámicas (junto con ALLOCATE y DEALLOCATE) permite gestionar mucho más eficientemente la memoria disponible por el programa, la cual es finita. Esto se hace evidente cuando tienes que gestionar un volumen de datos muy grande. Utiliza este tipo de variables para aquellas variables tipo dummy, las cuales las quieres sólo para recoger una información que luego se guarda en otro sitio, quedando dicha variable inútil.

9 - Procura compactar tu código al máximo. Un código de 500 líneas es infinitamente más sencillo de repasar, corregir y mejorar que uno de 2000 líneas.

10 - Existen un sin fin de tutoriales y webs donde se describen todas las funciones intrínsecas y consejos sobre programación. Es fácil caer en el error de que uno sabe hacer bien las cosas, pero por norma general siempre se pueden hacer mejor. Sólo es cuestión de informarse adecuadamente.

Espero que estos consejos os ayuden en vuestros proyectos de programación.


Un saludo