• Publicidad

Eficiencia de lectura de una matriz

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Eficiencia de lectura de una matriz

Notapor jorgedt » 2009-05-14 10:41 @487

Hola gente, escribo el post en esta sección para asegurarme de obtener una respuesta segura. Sucede que estoy programando una simulación "cosmológica" en Perl, y necesito conseguir la mejor eficiencia del código para que el script "vuele". Sucede que estoy trabajando con una matriz 3D de 1000x1000x3, y necesito saber cómo recorrerla con eficiencia... ya que también trabajo en ella otras 1000 veces más.

El programa me está demorando sus 6000 seg. aprox. en Ubuntu.

El ciclo es así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while ($t<=1000){
... 3 operaciones
for($i=1;$i<=1000;$i++){
    #...2 operaciones....
     for($j=$i+1;$j<=1000;$j++){
          #....2 operaciones
           for($k=1;$k<=3;$k++){
           #....4 operaciones del tipo:
            $a[$i][$j][$k]=...;
            $a[$j][$i][$k]=-$a[$i][$j][$k];
            $ac[$i][$k]=$ac[$i][$k]+$a[$i][$j][$k];
            $ac[$j][$k]=$ac[$j][$k]+$a[$j][$i][$k];
           }
     }
}
#...más operaciones
t++;
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Agradezco de antemano cualquier ayuda... eso.
:)
jorgedt
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2009-02-28 23:06 @004

Publicidad

Notapor explorer » 2009-05-14 10:57 @498

No es posible mejorar lo que has escrito, salvo que algunas de las operaciones que has escrito entre medias pueda ser cacheada con la ayuda del módulo Memoize.

La respuesta del foro Experto es... use PDL; Aprenderlo no es sencillo; tanto como aprender cualquier otra librería matemática; pero las prestaciones son tremendas.

Usa el sistema de paquetes de Ubuntu para localizar perl-pdl o perlpdl para instalarle. Luego, únete a su lista de correo. Existen un par de manuales, uno de ellos de introducción de Xavier Calbet.

Aquí tienes un ejemplo de uso.

Hay más comentarios sobre PDL en estos foros.

De todas formas, si nos das más detalles de lo que quieres hacer, podremos darte más pistas.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2009-05-16 07:28 @352

He visto que has modificado el mensaje casi al mismo tiempo de que respondiera.

Por las operaciones que has puesto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
            $a[$i][$j][$k]=...;
            $a[$j][$i][$k]=-$a[$i][$j][$k];
            $ac[$i][$k]=$ac[$i][$k]+$a[$i][$j][$k];
            $ac[$j][$k]=$ac[$j][$k]+$a[$j][$i][$k];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

se ve que es un ejemplo muy bueno para el uso de PDL.

Mientras tanto, se puede acelerar un poco el programa, optimizando de la misma forma que lo haríamos en C:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
            my $a_ijk = $a[$i][$j][$k] = ...;
            my $a_jik = $a[$j][$i][$k] = -$a_ijk;
            $ac[$i][$k] += $a_ijk;
            $ac[$j][$k] += $a_jik;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Bueno, la idea es intentar reducir los accesos a estructuras de datos, cacheando operaciones y valores intermedios. En algunas ocasiones, se aprecia un aumento de la velocidad de procesado.

De todas maneras, como ya digo, esto es más bien trabajo de PDL. O incluso hasta se podría hacer en Inline::C.

¿De qué operaciones estamos hablando? Sería interesante verlas...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor salva » 2009-05-18 02:29 @145

Un truco simple consiste en cambiar el orden de las dimensiones en la matriz:

Con tu esquema de 1000x1000x3 utilizas 1 millón de arrays para almacenar la matriz; si lo cambiases por 3x1000x1000, utilizarías solo 3000 arrays. Esto supondría un ahorro de memoria probablemente cercano al 50% que repercutiría en un aumento de la velocidad.

Otra solución es utilizar un único array para guardar toda la matriz y calcular el índice de cada elemento a mano (por ejemplo: $a[$i*3000+$j*3+$k]). El cálculo del índice, más o menos, tendrá un coste similar a las indirecciones, pero en la mayoría de los algoritmos se puede simplificar en función de los valores que tome en las iteraciones anteriores de los bucles con lo que podría ser más rápido. Una representación a medio camino con una matriz de 3x1000_000 también podría estar bien en algunos casos.

Bueno, no sé si se entiende lo que trato de decir demasiado bien... de todas formas mi consejo final también es que ¡¡¡uses PDL!!!
Avatar de Usuario
salva
Perlero nuevo
Perlero nuevo
 
Mensajes: 200
Registrado: 2008-01-03 15:19 @680


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron