Upload
doantuyen
View
219
Download
0
Embed Size (px)
Citation preview
REPUBLICA BOLIVARIANA DE VENEZUELA UNIVERSIDAD DEL ZULIA FACULTAD DE INGENIERÍA
DIVISIÓN DE ESTUDIOS PARA GRADUADOS PROGRAMA DE POSTGRADO EN COMPUTACIÓN APLICADA
BIBLIOTECA JAVA PARA LA SOLUCIÓN DE SISTEMAS DE
ECUACIONES LINEALES UTILIZANDO COMPUTACIÓN
DISTRIBUIDA
Trabajo de Grado presentado ante la Ilustre Universidad del Zulia
para optar al Grado Académico de:
MAGÍSTER SCIENTIARUM EN COMPUTACIÓN APLICADA
Autor: Miguel Ángel Leal Meza
Tutor: Carlos José Arévalo Concho
Co-Tutor: Nelson Eduardo Arapé Pérez
Maracaibo, Julio de 2013
Leal Meza, Miguel Ángel. Biblioteca Java para la solución de sistemas de ecuaciones lineales utilizando computación distribuida (2013). Trabajo de Grado. Universidad del Zulia. Facultad de Ingeniería. División de Postgrado. Maracaibo. Venezuela. 58p. Tutor: Carlos Arévalo. Co-Tutor: Nelson Arapé.
RESUMEN La solución de los sistemas de ecuaciones es un aspecto fundamental en el desarrollo de simuladores en áreas tan diversas como la industria aeroespacial, automotriz, electrónica y petrolera, dado que para la resolución de los modelos matemáticos de un sinnúmero de problemas reales en estos campos se deben solucionar los sistemas antes nombrados. Existen reconocidas bibliotecas para la solución de sistemas de ecuaciones en diferentes lenguajes tales como PETSc (Fortran, C, C++, Phyton), ASCEND (C, C++, Phyton, Tcl/Tk), entre otras. Por otro lado, Java ofrece reconocidas ventajas en materia de portabilidad, tiempo de desarrollo y mantenimiento, pero las bibliotecas disponibles en este lenguaje no trabajan bajo un ámbito distribuido. Por eso que en este trabajo se propone hacer una contribución para superar esa limitación. Para aprovechar las ventajas de los sistemas distribuidos en la resolución de sistemas de ecuaciones de gran porte se propone descomponer el sistema en subsistemas menores, los cuales pueden ser asignados a distintos procesadores de un sistema distribuido para su resolución empleando técnicas tradicionales dependiendo de las características del sistema. Por ejemplo, para los sistemas lineales es posible trabajar con métodos directos, tipo Gauss, o técnicas iterativas, tales como Jacobi. Para la evaluación de resultados, se tomara el tiempo de solución necesario para llegar a la respuesta, SpeedUp y Eficiencia, utilizando casos de prueba tomados de sitios especializados.
Palabras Clave: Ecuaciones lineales; Computación distribuida y paralela; Java Email del autor: [email protected]
Leal Meza, Miguel Ángel. Java library for solving linear equations systems using distributed computing (2013). Trabajo de Grado. Universidad del Zulia. Facultad de Ingeniería. División de Postgrado. Maracaibo. Venezuela. 58p. Tutor: Carlos Arévalo. Co-Tutor: Nelson Arapé.
ABSTRACT The solution of systems of equations is a fundamental aspect in the development of simulators in diverse areas such as aerospace, automotive, electronics and oil, since for the solution of mathematical models of a countless of real problems in these fields, those previously named systems must be solved. There are known libraries for solving systems of equations in different languages such as PETSc (Fortran, C, C + +, Python), ASCEND (C, C + +, Python, Tcl / Tk), among others. On the other hand, Java offers renowned advantages in terms of portability, development time and maintenance, but the libraries available in this language does not work under a distributed environment. Why in this work we propose to make a contribution to overcome this limitation. To take advantage of distributed systems in solving systems of equations of large size is proposed to decompose the system into smaller subsystems, which can be assigned to different processors of a distributed system for solving using traditional techniques depending on the characteristics of the system. For example, for linear systems it is possible to work with direct methods such Gaussian’s types, or iterative techniques such as Jacobi. For the evaluation of results, we take the time needed to reach solutions to the response, Speedup and efficiency using test cases taken from specialized sites. Key Words: Linear equations; Distributed and parallel computation; Java Author’s Email: [email protected]
DEDICATORIA
A mi dios, mamá, papá y Sit.
AGRADECIMIENTO
Antes que nada a Dios, por darme vida y salud para realizar este estudio que hoy
termina con este trabajo.
A mis padres, por su amor y siempre presente apoyo y porque sin ellos no sería quien
soy.
A mi esposa, por su apoyo incondicional y amor.
A los profesores Carlos y Nelson, quienes fueron el apoyo y fuente de conocimiento para
la realización de este trabajo.
A mi hermano Rubén, mis panas del post, Joe y J2, y a todas aquellas personas que de
una u otra manera colaboraron y estuvieron ahí para ayudarme.
¡Gracias!
TABLA DE CONTENIDO
Pagina
RESUMEN.............................................................................................. 3
ABSTRACT............................................................................................. 4
DEDICATORIA........................................................................................ 5
AGRADECIMIENTO.................................................................................. 6
TABLA DE CONTENIDO............................................................................ 7
LISTA DE TABLAS................................................................................... 9
LISTA DE FIGURAS ................................................................................. 10
INTRODUCCIÓN ..................................................................................... 11
CAPÍTULO
I EL PROBLEMA .......................................................................... 12
1.1. Planteamiento del problema .............................................. 12
1.2. Objetivos........................................................................ 13
1.3. Justificación y Delimitación de la Investigación..................... 13
II MARCO TEÓRICO..................................................................... 15
2.1. Lenguaje Java................................................................. 15
2.1.1. El Entorno de desarrollo Java....................................... 16
2.2. Computación Paralela....................................................... 18
2.2.1. Necesidad de la Computación Paralela........................... 18
2.2.2. Clasificación de la Computación Paralela........................ 20
2.2.3. Principales Usos de la Computación Paralela .................. 23
2.2.4. Principios del Diseño de Algoritmos Paralelos ................. 24
2.2.5. Métricas de Desempeño para Sistemas Paralelos ............ 25
2.2.6. Biblioteca Ibis............................................................ 25
2.3. Sistemas de Ecuaciones.................................................... 28
2.3.1. Ecuación................................................................... 28
2.3.2. Sistema de ecuaciones................................................ 29
2.3.3. Algoritmos de Solución de Ecuaciones Lineales ............... 30
2.4. Formatos para almacenamiento de matrices ........................ 33
2.4.1. Compressed Storage Row............................................ 33
2.4.2. Compressed Storage Column....................................... 34
2.4.3. Jagged Diagonal Storage............................................. 35
2.4.4. Transposed Jagged Diagonal Storage ............................ 36
III MARCO METODOLÓGICO ......................................................... 38
3.1. Tipo de Investigación ....................................................... 38
3.2. Metodología .................................................................... 38
3.2.1. Análisis de estructura de datos y método(s) de solución a
utilizar............................................................................... 38
3.2.2. Codificación de la librería ............................................ 39
3.2.3. Diseño e Implementación de casos de estudio................ 39
3.3. Herramientas y Equipos.................................................... 39
3.3.1. Hardware.................................................................. 39
3.3.2. Software................................................................... 39
IV DISEÑO DE LA BIBLIOTECA..................................................... 40
4.1. Biblioteca de Paralelización ............................................... 40
4.2. Estructuras de datos utilizadas .......................................... 40
4.3. Predicción de posibles futuros valores no cero...................... 41
4.4. Métodos de solución codificados......................................... 41
4.4.1. Gradiente conjugado .................................................. 41
4.4.2. Jacobi ...................................................................... 42
4.4.3. Eliminación Gaussiana ................................................ 43
V CASOS DE ESTUDIO Y RESULTADOS.......................................... 45
5.1. Casos de estudio ............................................................. 45
5.2. Métricas de medición de desempeño................................... 45
5.2.1. Speed up .................................................................. 45
5.2.2. Eficiencia .................................................................. 46
5.3. Hardware utilizado en las pruebas...................................... 46
5.4. Algoritmo Gradiente Conjugado ......................................... 47
5.5. Algoritmo Jacobi .............................................................. 49
5.6. Algoritmo Eliminación Gaussiana........................................ 51
CONCLUSIONES..................................................................................... 54
RECOMENDACIONES............................................................................... 55
BIBLIOGRAFÍA ....................................................................................... 56
LISTA DE TABLAS
Tabla Página
1. Tiempo de ejecución Gradiente Conjugado en GOD.................................. 47
2. Tiempo de ejecución Gradiente Conjugado en SER................................... 48
3. Tiempo de ejecución Jacobi en GOD ...................................................... 49
4. Tiempo de ejecución Jacobi en SER ....................................................... 50
5. Tiempo de ejecución Eliminación Gaussiana en GOD ................................ 51
6. Tiempo de ejecución Eliminación Gaussiana en SER ................................. 52
LISTA DE FIGURAS
Figura Página
1. Estructura de Biblioteca IBIS [6]........................................................... 26
2. Llamado de Objetos en GMI [15] .......................................................... 26
3. Sistema de Ecuaciones ........................................................................ 29
4. Estructura de Sistema de Ecuaciones..................................................... 29
5. Reescritura de Sistema de Ecuaciones ................................................... 29
6. Matriz Dispersa .................................................................................. 34
7. Representación de Compressed Storage Row.......................................... 34
8. Representación de Compressed Storage Column ..................................... 35
9. Representación de Jagged Diagonal Storage ........................................... 36
10. Representación de Transpossed Jagged Diagonal Storage ....................... 37
11. Speed Up Gradiente Conjugado en GOD............................................... 47
12. Eficiencia Gradiente Conjugado en GOD ............................................... 48
13. Speed Up Gradiente Conjugado en SER................................................ 48
14. Eficiencia Gradiente Conjugado en SER ................................................ 49
15. Speed Up Jacobi en GOD.................................................................... 49
16. Eficiencia Jacobi en GOD .................................................................... 50
17. Speed Up Jacobi en SER .................................................................... 50
18. Eficiencia Jacobi en SER..................................................................... 51
19. Speed Up Eliminación Gaussiana en GOD ............................................. 51
20. Eficiencia Eliminación Gaussiana en GOD.............................................. 52
21. Speed Up Eliminación Gaussiana en SER .............................................. 52
22. Eficiencia Eliminación Gaussiana en SER............................................... 53
INTRODUCCIÓN
Problemas críticos en las más diversas industrias tales como la petrolera (e.g.,
simulación de yacimientos), automotríz (e.g., análisis de impacto) y aeroespacial (e.g.,
diseño de alas de aviones), requieren de la solución de sistemas de ecuaciones lineales,
típicamente de dimensiones considerables. En la solución de estos sistemas, se utilizan
bibliotecas especializadas de optimización sobre plataformas de cómputo distribuidas. Las
más reconocidas bibliotecas son PetSc [1] y la conocida como IMSL [2].
Un número creciente de aplicaciones de ingeniería están siendo desarrolladas en Java
debido a las ventajas que ofrece en materia de portabilidad, mantenimiento y tiempo de
desarrollo. Es posible invocar bibliotecas existentes en lenguajes C y C++ mediante un
mecanismo conocido como Java Native Interface, (JNI) pero el desarrollo de una interfaz JNI
para una biblioteca de la complejidad de por ejemplo PetSc requiere un esfuerzo
considerable y la solución sería menos portable a diferentes sistemas operativos que una
basada totalmente en Java.
Existen varias bibliotecas escritas en Java para la solución de sistemas de ecuaciones,
algunas de las cuales son Michael Thomas Flanagan's Java Scientific Library, codificada por
el profesor Michael Thomas y sus alumnos de la UCL (University College London) [3],
Jampack (University of MaryLand y National Institute of Standards and Technology) [4] y
Matrix toolkit for Java (Bjørn-Ove Heimsund) [5], entre otras; pero ninguna posee la
capacidad de trabajar bajo clusters de computadoras (Computación Distribuida).
La presente investigación se propone superar estas limitaciones desarrollando una
biblioteca para la solución de sistemas de ecuaciones lineales sobre una plataforma de
clusters de computadoras. Los métodos a ser codificados incluyen: Gradiente Conjugado,
Eliminación Gaussiana y Jacobi. Se pretende utilizar como tecnología de comunicación la
biblioteca IBIS, proyecto de código abierto para el manejo de eficiente de computación en
grids (mallas) y clusters, desarrollado por la facultad de Ciencias en la Vrije Universiteit de
Amsterdam [6].
CAPÍTULO I
EL PROBLEMA
En este capítulo se abordan aspectos relacionados con el asunto en estudio, con ello se
identifica formalmente el problema en investigación; igualmente, este planteamiento se
formula de forma clara como una pregunta. También se enuncian los objetivos que se
desean alcanzar en la investigación, y finalmente la justificación y delimitación de la misma.
1.1. Planteamiento del Problema
Problemas críticos en las más diversas industrias tales como la petrolera (e.g.,
simulación de yacimientos), automotríz (e.g., análisis de impacto) y aeroespacial (e.g.,
diseño de alas de aviones), requieren de la solución de sistemas de ecuaciones lineales,
típicamente de dimensiones considerables. En la solución de estos sistemas, se utilizan
bibliotecas especializadas de optimización sobre plataformas de cómputo distribuidas. Las
más reconocidas bibliotecas son PetSc [1] y la conocida como IMSL [2].
Un número creciente de aplicaciones de ingeniería están siendo desarrolladas en Java
debido a las ventajas que ofrece en materia de portabilidad, mantenimiento y tiempo de
desarrollo. Es posible invocar bibliotecas existentes en lenguajes C y C++ mediante un
mecanismo conocido como Java Native Interface, (JNI) pero el desarrollo de una interfaz JNI
para una biblioteca de la complejidad de por ejemplo PetSc requiere un esfuerzo
considerable y la solución sería menos portable a diferentes sistemas operativos que una
basada totalmente en Java.
Existen varias bibliotecas escritas en Java para la solución de sistemas de ecuaciones,
algunas de las cuales son Michael Thomas Flanagan's Java Scientific Library, codificada por
el profesor Michael Thomas y sus alumnos de la UCL (University College London) [3],
Jampack (University of MaryLand y National Institute of Standards and Technology) [4] y
Matrix toolkit for Java (Bjørn-Ove Heimsund) [5], entre otras; pero ninguna posee la
capacidad de trabajar bajo clusters de computadoras (Computación Distribuida).
13
La presente investigación se propone superar estas limitaciones desarrollando una
biblioteca para la solución de sistemas de ecuaciones lineales sobre una plataforma de
clusters de computadoras. Los métodos a ser codificados incluyen: Gradiente Conjugado,
Eliminación Gaussiana y Jacobi. Se pretende utilizar como tecnología de comunicación la
biblioteca IBIS, proyecto de código abierto para el manejo de eficiente de computación en
grids (mallas) y clusters, desarrollado por la facultad de Ciencias en la Vrije Universiteit de
Amsterdam [6].
1.2. Objetivos
a. Objetivo General
• Creación de una biblioteca Java para la solución en paralelo de sistemas de
ecuaciones lineales que pueda ser utilizada en clusters de computadoras.
b. Objetivos Específicos
• Realizar un estudio de algoritmos paralelos para la solución de sistemas de
ecuaciones y seleccionar los más apropiados.
• Desarrollar una biblioteca que codifique los métodos seleccionados, utilizando la
biblioteca IBIS para el manejo de la arquitectura distribuida.
• Seleccionar los casos de estudio para verificar el correcto funcionamiento de la
biblioteca desarrollada.
• Evaluar el desempeño de la biblioteca utilizando un ambiente de pruebas controlado.
1.3. Justificación y Delimitación de la Investigación
a. Justificación
• Un número creciente de aplicaciones de ingeniería están siendo desarrolladas en Java
debido a las ventajas que ofrece en materia de portabilidad, mantenimiento y tiempo
de desarrollo, mas no existen bibliotecas para la solución en paralelo de sistemas de
ecuaciones lineales en plataformas distribuidas (e.g., clusters de computadoras).
• Existen otras bibliotecas en otros lenguajes las cuales son ampliamente utilizadas,
podrían ser llamadas desde Java mediante JNI, pero requiere un gran esfuerzo y la
solución final es más difícil de portar a diferentes sistemas operativos.
14
• Existen bibliotecas disponibles para calcular ecuaciones lineales en lenguaje Java,
mas las mismas carecen de la capacidad de ser utilizadas en plataformas distribuidas.
b. Delimitación
• Se codificará los métodos de resolución de ecuaciones lineales Eliminación Gaussiana
(con estructuras de datos por fila y columna), Jacobi y Gradiente Conjugado.
• Se programará en Lenguaje Java, utilizando la biblioteca de comunicación paralela
IBIS y en el Entorno de Desarrollo NetBeans.
• Se realizarán pruebas para medir tiempo de ejecución, aumento de velocidad (speed-
up) y eficiencia.
CAPÍTULO II
MARCO TEÓRICO
2.1. Lenguaje Java
Explican en [7] que el lenguaje Java surgió en 1991 cuando un grupo de ingenieros de la
entonces Sun Microsystems trataron de diseñar un nuevo lenguaje de programación
destinado a electrodomésticos. La reducida potencia de cálculo y memoria de los
electrodomésticos llevó a desarrollar un lenguaje sencillo capaz de generar código de
tamaño muy reducido. Actualmente Java se ejecuta en más de 850 millones de ordenadores
personales de todo el mundo y en miles de millones de dispositivos, como dispositivos
móviles y aparatos de televisión.
Debido a la existencia de distintos tipos de CPUs y a los continuos cambios, era
importante conseguir una herramienta independiente del tipo de CPU utilizada. Desarrollaron
un código “neutro” que no dependía del tipo de electrodoméstico, el cual se ejecutaba sobre
una “máquina hipotética o virtual” denominada Java Virtual Machine (JVM). Era la JVM quien
interpretaba el código neutro convirtiéndolo a código particular de la CPU utilizada. Esto
permitía lo que luego se ha convertido en el principal lema del lenguaje: “Write Once, Run
Everywhere”. A pesar de los esfuerzos realizados por sus creadores, ninguna empresa de
electrodomésticos se interesó por el nuevo lenguaje.
Como lenguaje de programación para computadores, Java se introdujo a finales de 1995.
La clave fue la incorporación de un intérprete Java en la versión 2.0 del programa Netscape
Navigator, produciendo una verdadera revolución en Internet. Java 1.1 apareció a principios
de 1997, mejorando sustancialmente la primera versión del lenguaje. Java 1.2, más tarde
rebautizado como Java 2, nació a finales de 1998, luego vinieron las versiones J2SE 1.3 (8
de mayo de 2000), J2SE 1.4 (6 de febrero de 2002), J2SE 5.0 (30 de septiembre de 2004),
Java SE 6 (11 de diciembre de 2006) y Java SE 7 lanzada en Julio de 2011.
Según sus creadores, el lenguaje Java se creó con cinco objetivos principales:
16
• Debería usar el paradigma de la programación orientada a objetos.
• Debería permitir la ejecución de un mismo programa en múltiples sistemas
operativos.
• Debería incluir por defecto soporte para trabajo en red.
• Debería diseñarse para ejecutar código en sistemas remotos de forma segura.
• Debería ser fácil de usar y tomar lo mejor de otros lenguajes orientados a objetos,
como C++.
Al programar en Java no se parte de cero. Cualquier aplicación que se desarrolle se
apoya en un gran número de clases preexistentes. Algunas de ellas las ha podido hacer el
propio usuario, otras pueden ser comerciales, pero siempre hay un número muy importante
de clases que forman parte del propio lenguaje (el API o Application Programming Interface
de Java).
Java incorpora en el propio lenguaje muchos aspectos que en cualquier otro lenguaje son
extensiones propiedad de empresas de software o fabricantes de ordenadores (hilos,
ejecución remota, componentes, seguridad, acceso a bases de datos, etc.).
2.1.1. El entorno de desarrollo Java
Existen distintos programas comerciales que permiten desarrollar código Java. La
compañía Oracle, quien compro Sun, creadora de Java, distribuye gratuitamente el Java(tm)
Development Kit (JDK). Se trata de un conjunto de programas y librerías que permiten
desarrollar, compilar y ejecutar programas en Java. Incorpora además la posibilidad de
ejecutar parcialmente el programa, deteniendo la ejecución en el punto deseado y
estudiando en cada momento el valor de cada una de las variables (con el denominado
Debugger).
Cualquier programador con un mínimo de experiencia sabe que una parte muy
importante (muchas veces la mayor parte) del tiempo destinado a la elaboración de un
programa se destina a la detección y corrección de errores. Existe también una versión
reducida del JDK, denominada JRE (Java Runtime Environment) destinada únicamente a
ejecutar código Java (no permite compilar).
Los IDEs (Integrated Development Environment), tal y como su nombre indica, son
entornos de desarrollo integrados. En un mismo programa es posible escribir el código Java,
compilarlo y ejecutarlo sin tener que cambiar de aplicación. Algunos incluyen una
17
herramienta para realizar debug gráficamente, frente a la versión que incorpora el JDK
basada en la utilización de una consola bastante difícil y pesada de utilizar. Estos entornos
integrados permiten desarrollar las aplicaciones de forma mucho más rápida, incorporando
en muchos casos librerías con componentes ya desarrollados, los cuales se incorporan al
proyecto o programa. Como inconvenientes se pueden señalar algunos fallos de
compatibilidad entre plataformas, y ficheros resultantes de mayor tamaño que los basados
en clases estándar.
a. El compilador de Java
Se trata de una de las herramientas de desarrollo incluidas en el JDK. Realiza un análisis
de sintaxis del código escrito en los ficheros fuente de Java (con extensión*.java). Si no
encuentra errores en el código genera los ficheros compilados (con extensión *.class). En
otro caso muestra la línea o líneas erróneas. En el JDK de Sun dicho compilador se llama
“javac”. Tiene numerosas opciones, algunas de las cuales varían de una versión a otra. Se
aconseja consultar la documentación de la versión del JDK utilizada para obtener una
información detallada de las distintas posibilidades.
b. Java Virtual Machine
Tal y como se ha resaltado previamente, la existencia de distintos tipos de procesadores
y ordenadores llevó a los ingenieros de Sun a la conclusión de que era muy importante
conseguir un software que no dependiera del tipo de procesador utilizado. Se planteó la
necesidad de conseguir un código capaz de ejecutarse en cualquier tipo de máquina. Una
vez compilado no debería ser necesaria ninguna modificación por el hecho de cambiar de
procesador o de ejecutarlo en otra máquina. La clave consistió en desarrollar un código
“neutro” el cual estuviera preparado para ser ejecutado sobre una “máquina hipotética o
virtual”, denominada Java Virtual Machine (JVM). Es esta JVM quien interpreta este código
neutro convirtiéndolo a código particular de la CPU utilizada. Se evita tener que realizar un
programa diferente para cada CPU o plataforma.
La JVM es el intérprete de Java. Ejecuta los “bytecodes” (ficheros compilados con
extensión *.class) creados por el compilador de Java (javac). Tiene numerosas opciones
entre las que destaca la posibilidad de utilizar el denominado JIT (Just-In-Time Compiler),
que puede mejorar entre 10 y 20 veces la velocidad de ejecución de un programa.
18
2.2. Computación Paralela
Como se explica en [8], la Computación Paralela consiste en la explotación de varios
procesadores para que trabajen de forma conjunta en la resolución de un problema
computacional. Normalmente cada procesador trabaja en una parte del problema y se
realiza intercambio de datos entre los procesadores.
2.2.1. Necesidad de la Computación Paralela
En los últimos años los sistemas distribuidos cobraron gran importancia debido a las
crecientes mejoras en las redes de computadoras. La reciente adopción masiva por parte de
la industria de esta tecnología hizo posible una gran disponibilidad de plataformas de
computación distribuida a bajo costo.
Actualmente, muchas grandes compañías de Internet usan computación distribuida para
poder dar basto a la gran cantidad de solicitudes que reciben sus sitios en Internet,
balanceando las peticiones de los usuarios entre la gran cantidad de servidores que poseen,
un ejemplo de esto es Google, empresa de Internet que se estima tiene millones de
servidores repartidos en el mundo [9].
Otro proyecto muy importante que usa tecnología paralela, pero desde otro enfoque es
SETI@home, el cual consiste en miles de PC de personas comunes repartidos por Internet,
entre ellos el autor del presente trabajo, que quieren colaborar con el proyecto y que ceden
tiempo de sus procesadores durante ciclos de proceso desocupados, para analizar señales
buscando patrones inteligentes extraterrestres [10].
En el 2001 fue el lanzamiento del primer procesador multi-núcleo, el Power4 de IBM
[11], mas fue en el 2005 con el lanzamiento del Intel Pentium D y el AMD Athlon 64 X2, que
se comenzó a popularizar las computadoras con múltiples procesadores para las masas,
años más tarde, en el 2011 con el lanzamiento del LG Optimus 2x esta tendencia fue
transmitida a teléfonos celulares [12], haciendo que el software paralelo deje de ser
exclusivo de ambientes especializados y de computación de alto desempeño y que el uso y
desarrollo eficiente de sistemas distribuidos y paralelos sea recientemente un tópico de gran
importancia.
a. El Poder Computacional
19
En 1965, el Sr. Gordon Moore (co-fundador de Intel) hizo una observación (comúnmente
llamada Ley de Moore), en la cual él anticipaba que la complejidad de los circuitos
integrados se duplicaría cada año con una reducción de costo conmensurable. Moore
actualizó su predicción en 1975 para señalar que el número de transistores en un chip se
duplica cada dos años y esto se sigue cumpliendo hoy. Hasta hace unos años se cumplía en
procesadores de un solo núcleo, lo cual hacia que los Megahertz y luego los Gigahertz que
los mismos manejaban crecieran de manera acelerada.
Esta aceleración continuó hasta que la tecnología se topo con una barrera: el aumento
en el calentamiento de los procesadores al incrementar la velocidad y la cantidad de
componentes, además de esto, la imposibilidad de aumentar el tamaño de los componentes
debido al tiempo de propagación de las señales dentro de los chips. La solución a esto fue
cambiar velocidad de procesadores por redundancia, o sea, paralelismo.
En la actualidad el número de transistores sigue creciendo, mas la tendencia es en
múltiples núcleos, procesadores que pueden realizar más de una tarea en un ciclo del reloj,
en pocas palabras, computación paralela. Esta posibilidad se ha universalizado
recientemente, al haber sustituido en la práctica los sistemas multinúcleo a los
monoprocesadores como sistema universal de cómputo, ya que en la actualidad los
procesadores duales se comercializan como procesador básico, y es posible adquirir sin
mucho coste también tetraprocesadores.
Los procesadores de propósito específico también están adquiriendo importancia como
sistemas paralelos de propósito general. Así, hay procesadores gráficos, DSP,
FPGA, procesadores embebidos, procesadores para juegos (PS3, Xbox, etc.), que se utilizan
en muchos casos para desarrollar software para el que no estaban pensados inicialmente, un
ejemplo de esto es el Cluster Condor, desarrollado por la Fuerza Aérea de Estados Unidos
utilizando 1.760 consolas PS3.
b. Velocidad de Disco / Memoria
La velocidad global del computador está determinada no solamente por la velocidad del
procesador, sino también por la capacidad de la memoria del sistema para alimentarlo. Si
bien la capacidad de los procesadores ha aumentado en aproximadamente un 40% por año
durante los últimos 15 años, los tiempos de acceso RAM sólo han mejorado a un ritmo de
aproximadamente el 10% por año durante este intervalo, esta brecha entre la velocidad del
20
procesador y la memoria se presenta un cuello de botella tremendo. Este desajuste
creciente entre la velocidad del procesador y la latencia de memoria RAM es típicamente
puenteada por una jerarquía de dispositivos de memoria más rápida llamados cache que se
basan en la localidad de datos de referencia para ofrecer un mayor rendimiento del sistema
de memoria.
Las plataformas paralelas generalmente ceden un mejor rendimiento de memoria del
sistema, porque proporcionan (i) caches más grandes, y (ii) mayor ancho de banda total del
sistema de memorias (típicamente lineal al número de procesadores). Este argumento se
puede extender a los discos donde plataformas paralelas pueden lograr un alto ancho de
banda agregado a un almacenamiento secundario. De hecho, algunos de las más crecientes
áreas de aplicación de la computación paralela en los servidores de datos (servidores de
bases de datos, servidores web) no es tanto en sus altas tasas de cómputo global, sino en la
capacidad de proveer salida de datos a mayor velocidad.
c. La Comunicación de Datos
A medida que las infraestructuras de redes evolucionan, la visión de usar Internet como
un gran ambiente de computación distribuido ha comenzado a tomar forma. Algunas de las
plataformas de las más impresionantes aplicaciones paralelas masivas han sido en el
contexto WAN (Wide Area Network). Por ejemplo, el ya señalado proyecto SETI.
2.2.2. Clasificación de la Computación Paralela
Han sido identificadas varias clasificaciones de la computación paralela, según explican
en [13], las más destacadas han sido:
• Clasificación basada en las instrucciones.
• Clasificación basada en como la memoria es accedida.
a. Clasificación basada en las instrucciones
Esta clasificación fue primeramente estudiada y propuesta por Michael Flynn en 1972.
Flynn no consideró la arquitectura de la máquina para la clasificación de computadoras
paralelas, en lugar de eso, se basa en el número de instrucciones concurrentes (control) y
en los flujos de datos disponibles en la arquitectura. [14]
21
• Una instrucción, un dato (SISD): Computador secuencial que no explota el
paralelismo en las instrucciones ni en flujos de datos. Ejemplos de arquitecturas SISD
son las máquinas con uni-procesador o monoprocesador tradicionales como el PC o
los antiguos mainframe.
• Múltiples instrucciones, un dato (MISD): Poco común debido al hecho de que la
efectividad de los múltiples flujos de instrucciones suele precisar de múltiples flujos
de datos. Sin embargo, este tipo se usa en situaciones de paralelismo redundante,
como por ejemplo en navegación aérea, donde se necesitan varios sistemas de
respaldo en caso de que uno falle. También se han propuesto algunas arquitecturas
teóricas que hacen uso de MISD, pero ninguna llegó a producirse en masa.
• Una instrucción, múltiples datos (SIMD): Un computador que explota varios
flujos de datos dentro de un único flujo de instrucciones para realizar operaciones
que pueden ser paralelizadas de manera natural. Por ejemplo, un procesador
vectorial.
• Múltiples instrucciones, múltiples datos (MIMD): Varios procesadores
autónomos que ejecutan simultáneamente instrucciones diferentes sobre datos
diferentes. Los sistemas distribuidos suelen clasificarse como arquitecturas MIMD;
bien sea explotando un único espacio compartido de memoria, o uno distribuido.
b. Clasificación basada en como la memoria es accedida
La memoria principal en un ordenador en paralelo puede ser compartida entre todos los
elementos de procesamiento en un único espacio de direcciones, o distribuida, esto es cada
elemento de procesamiento tiene su propia memoria local.
- Memoria Compartida
El modelo de memoria compartida (Shared Memory Model) es aquel sistema que posee
una sola memoria pero la misma compartida para todos los procesadores, en esta
arquitectura, múltiple procesadores pueden operar independientemente pero comparten los
mismos recursos de memoria, lo que implica que cambios en memoria hechos por un
procesador afecta inmediatamente lo que pueden acceder los otros. Históricamente, estos
han sido clasificados como UMA (Uniform Memory Access / Acceso Uniforme a Memoria) y
22
NUMA (Non-Uniform Memory Access / Acceso a Memoria no Uniforme), basados en el tiempo
de acceso a la memoria.
• Uniform Memory Access (UMA): Todos los proceso en el modelo UMA acceden a la
memoria de manera uniforme, es decir, el tiempo de acceso o la localización de
memoria es independiente del proceso que realiza la petición o del chip de memoria
donde se encuentre el dato solicitado, mas cada procesador puede utilizar una caché
privada.
• Non-Uniform Memory Access (NUMA): es un diseño utilizado en
multiprocesamiento donde la memoria se accede en posiciones relativas de otro
proceso o memoria compartida entre procesos. Bajo NUMA, un procesador puede
acceder a su propia memoria local de forma más rápida que a la memoria no local
(memoria local de otro procesador o memoria compartida entre procesadores). NUMA
ofrece memoria distribuida para cada procesador, evitando así que afecte al
rendimiento del sistema cuando varios procesadores intentan acceder a la misma
memoria. Para los problemas de la propagación de datos (comunes en servidores y
aplicaciones similares), NUMA puede mejorar el rendimiento utilizando una única
memoria compartida por un factor de aproximadamente el número de procesadores
(o separando bancos de memoria).
- Memoria Distribuida
Este es el modelo donde cada procesador tiene asociado un bloque de memoria al que
puede acceder directamente, y ningún procesador puede acceder directamente a bloques de
memoria asociados a otros procesadores. Así, para llevar a cabo el intercambio de datos
será necesario que cada procesador realice explícitamente la petición de datos al procesador
que dispone de ellos, y este procesador haga un envío de los datos.
Por sus características, se dice que los sistemas distribuidos son tolerantes a fallos, ya
que si un componente del sistema se descompone otro componente debe ser capaz de
reemplazarlo.
23
2.2.3. Principales Usos de la Computación Paralela
La computación paralela ha tenido un gran impacto en áreas que van desde simulaciones
computacionales para aplicaciones científicas y de ingeniería hasta aplicaciones comerciales
que utilizan minería de datos o procesamiento de transacciones.
a. Ejemplo de las diversas aplicaciones de la computación paralela
Aplicación en Ingeniería y Diseño: La computación paralela ha sido usada
tradicionalmente con gran éxito en el diseño de airfoils (perfiles de ala), motores de
combustión interna, circuitos de alta velocidad, estructuras, entre otros. Recientemente,
también en el diseño de sistemas microelectromecánicos y nanoelectromecánicos
(MEMS y NEMS). Otras aplicaciones en Ingeniería y diseño se enfocan en la optimización
de una variedad de procesos. La computación paralela ha sido usada durante mucho
tiempo para la solución de incontables problemas de optimización discreta y continua.
Aplicaciones Científicas: El análisis de secuencias biológicas con la visión de desarrollar
nuevas medicinas y curas para enfermedades y condiciones médicas requieren
algoritmos innovadores además de poder de cómputo a gran escala. El procesamiento
requerido para el secuenciamiento del genoma humano realizado por The International
Human Genome Sequencing Consortium and Celera, Inc., fue posible gracias a el uso de
tecnologías paralelas, incluso, algunos de las mas nuevos avances es esta área están
dirigidas específicamente a aplicaciones en Bioinformática.
Aplicaciones Comerciales: Plataformas paralelas, desde computadoras multiprocesador
hasta cluster Linux son frecuentemente usados como servidores Web y de base de
datos. Por ejemplo, en días de gran volumen, grandes casas de Wall Street manejan
cientos de miles de sesiones de usuario simultáneas y millones de órdenes.
Aplicaciones en Sistemas de Computadoras: A medida de que la computación se
dispersa a través de la red, problemas de procesamiento paralelo se vuelven arraigados
a una variedad de aplicaciones. En seguridad informática, la detección de intrusos es un
gran reto, y para tener éxito, la data debe ser recopilada en lugares dispersos y debe
ser rápidamente analizada, la inviabilidad de recolectar esta data a un sitio central para
análisis requiere algoritmos paralelos efectivos.
Estos fueron solo algunos ejemplos de todas las aplicaciones de la computación paralela
en el área de sistemas.
24
2.2.4. Principios del Diseño de Algoritmos Paralelos
Un algoritmo secuencial es esencialmente una secuencia de pasos básicos para
solucionar un problema dado. Similarmente, un algoritmo paralelo es un récipe que nos dice
cómo solucionar un problema dado, pero usando múltiples procesadores. Sin embargo,
especificar un algoritmo paralelo implica más que solo especificar los pasos. El diseñador del
algoritmo debe especificar cuáles de esos pasos pueden ser ejecutados simultáneamente, lo
cual es esencial si se desea obtener algún beneficio de desempeño en el uso de sistemas
paralelos.
En la práctica, el diseño de algún algoritmo paralelo puede incluir algunos de los
siguientes pasos:
• Identificar porciones del trabajo que pueden ser realizadas al mismo tiempo.
• Asignación de las piezas de trabajo en procesos corriendo en paralelo.
• Distribuir la entrada, salida y data intermedia asociada con el programa.
• Manejar el acceso a data compartida por múltiples procesadores.
• Sincronizar los procesadores en varias etapas de la ejecución del programa paralelo.
Típicamente, hay varias opciones para cada uno de los pasos descritos arriba, pero
usualmente, relativamente pocas combinaciones de opciones llevan a un algoritmo paralelo
que provee un rendimiento proporcional a los recursos computacionales y de
almacenamiento empleados para solucionar el problema.
2.2.5. Métricas de Desempeño para Sistemas Paralelos
Es importante estudiar el desempeño de programas paralelos como una manera de
determinar el mejor algoritmo, evaluando la plataforma de hardware y examinando los
beneficios del paralelismo. Un número de métricas han sido utilizadas basadas en el
resultado deseado del análisis de desempeño.
• Tiempo de ejecución: El tiempo serial de un programa es el tiempo enlazado entre
el inicio y el final de su ejecución de manera secuencial. El tiempo paralelo es el
tiempo que enlaza desde el momento que la computación paralela comienza hasta el
momento que el último elemento de procesamiento termina su ejecución.
25
• Aumento de Velocidad (Speed Up): Cuando evaluamos un sistema paralelo, se
está interesado en saber cuánto desempeño se gano al paralelizar una aplicación
dada. Esto es, capturar el beneficio relativo de resolver un problema en paralelo, o la
relación del tiempo tomado en solucionar un problema en un solo elemento de
procesamiento al tiempo tomado para resolver el mismo problema con p elementos
de procesamiento.
• Eficiencia: Solo un sistema paralelo ideal conteniendo p elementos de
procesamiento puede entregar un aumento de velocidad de p. En la práctica, parte
del tiempo requerido por los elementos de procesamiento para computar la suma de
n números es gastado comunicándose. Eficiencia es la medida de la fracción del
tiempo en el cual un elemento de procesamiento es útilmente empleado. En un
sistema ideal, el aumento de velocidad es igual a p y la eficiencia es igual a 1. En la
práctica, el aumento es menor que p y la eficiencia es entre 0 y 1, dependiendo de la
efectividad en la cual los elementos de procesamiento son usados.
2.2.6. Biblioteca Ibis
Ibis es un proyecto Java OpenSource para aplicaciones que corran en Grids y Clusters. Es
un software desarrollado por la Universidad de Vrije, Holanda. Está diseñado con una
arquitectura multicapas. Haciendo uso de Ibis, puede desarrollarse software que se ejecute
de una forma fiable y eficiente en un entorno paralelo. Gracias a esta, los programas pueden
hacer uso de redes de alta velocidad a la vez que siguen manteniendo su portabilidad.
Es posible escribir programas Ibis usando varios modelos de programación como por
ejemplo Java RMI, modelos que soporten comunicaciones de grupo, modelos de divide y
vencerás y con paso de mensajes.
La misma trabaja bajo una licencia GNU Library or Lesser General Public License (LGPL)
y multiplataforma trabajando en los Sistemas Unix, Linux y Windows [6].
a. Modelos de programación de IBIS
Se pueden utilizar varios modelos de programación en el proyecto Ibis dependiendo del
tipo de algoritmo paralelo que se vaya a diseñar.
• RMI: La interfaz estándar para la comunicación entre objetos en Java.
26
• Group method invocation (GMI): es una generalización del modelo RMI con
soporte para grupos de operaciones.
• Satin: Un modelo de programación divide y vencerás.
• MPJ: Paso de mensajes MPI codificado en Java.
• RepMI: Un modelo de tipo RMI que soporta duplicación de objetos.
Figura 1. Estructura de Biblioteca IBIS [6]
b. GMI
Según podemos leer en [15], este modelo generaliza el modelo RMI e introduce la noción
de “grupo”, que no es más que un grupo de objetos quienes implementan la misma interfaz
y son distribuidos a través de varias JVM. Pueden ser llamados a través de una sola
referencia al grupo, o individualmente.
Figura 2. Llamado de objetos en GMI [15]
A continuación, las diferentes invocaciones a objetos que puede realizar GMI:
27
• Single Invocation (invocación simple): La invocación es realizada a un solo objeto,
identificando a cual por su rango.
• Group Invocation (invocación de grupo): La invocación es realizada a cada objeto del
grupo.
• Personalized Group Invocation (invocación personalizada de grupo): Se invoca a cada
objeto en el grupo, mas sin embargo, los parámetros son personalizados para cada
objeto.
• Combined Invocation (invocación combinada): Múltiples hilos invocan el mismo
método en el mismo grupo.
También existen varios métodos para la obtención de los resultados:
• Discard Results (desechar resultados): No retorna resultados (para los tipos de
métodos void).
• Return One Result (retornar un solo resultado): Un solo resultado es retornado,
preseleccionado por rango si es necesario.
• Foward Results (reenviar resultados): Todos los resultados son retornados, pero son
enviados a un objeto definido por el usuario.
• Combine Results (combinar resultados): Combina todos los resultados en uno solo
utilizando un método definido por el usuario.
El modelo GMI esta soportado por varios servicios que son necesarios para su
funcionamiento:
• Pool: El concepto central de Ibis es el pool (piscina), el cual consiste de una o más
instancias Ibis, usualmente corriendo en distintos procesadores.
• Servidor Ibis: Es quien se encarga de llevar el control del proceso, desde el registro
de las instancias en la pool, hasta enrrutar el trafico a través de las distintas
instancias.
28
2.3. Sistemas de Ecuaciones
2.3.1. Ecuación
Según leído en [16], es la igualdad entre dos expresiones matemáticas. Las primeras
ecuaciones estudiadas fueron las algébricas, obtenidas igualando entre sí polinomios
diversos en las incógnitas a indagar.
Según se explica en [17], en una ecuación pueden figurar letras cuyos valores se
suponen conocidos, y que se denominan parámetros; las restantes letras que en ella figuran
son las incógnitas. Las cantidades conocidas están representadas por letras, con objeto de
tratar al mismo tiempo todos los problemas análogos que solo difieren entre sí por los
valores de los datos. Las incógnitas suelen representarse por las últimas letras del alfabeto.
Para resolver una ecuación se deben hallar todas sus raíces, Si x =a es raíz de una
ecuación, se dice que la ecuación se satisface para x = a. Cabe destacar que una ecuación
puede carecer de raíces.
2.3.2. Sistema de ecuaciones
Cuando varias ecuaciones deben quedar satisfechas para un mismo sistema de valores
de las incógnitas, se dice que forman un sistema. Dos sistemas de ecuaciones son
equivalentes cuando las ecuaciones de cada uno de ellos son verificadas por un mismo
sistema de valores de las incógnitas.
Para establecer la equivalencia entre dos sistemas de ecuaciones hay que demostrar que
toda solución del primer sistema es solución del segundo y recíprocamente. Dos sistemas de
ecuaciones equivalentes a un tercero son equivalentes entre sí.
Resolver un sistema de ecuaciones es obtener todos los sistemas de valores de las
incógnitas que satisfacen a las ecuaciones, es decir que, al sustituir a las incógnitas,
transforman las ecuaciones del sistema en igualdades numéricas, en el siguiente ejemplo
seria encontrar los valores desconocidos de las variables x1, x2 y x3 que satisfacen las tres
ecuaciones.
29
⎪⎪⎪
⎭
⎪⎪⎪
⎬
⎫
⎪⎪⎪
⎩
⎪⎪⎪
⎨
⎧
−−
−
021
24x2x2x
12x3x
32
1
321
321
xx+x
++
x++
Figura 3. Sistema de Ecuaciones
El problema de los sistemas lineales de ecuaciones es uno de los más antiguos de la
matemática y tiene una infinidad de aplicaciones, como en procesamiento digital de señales,
estimación, predicción y más generalmente en programación lineal así como en la
aproximación de problemas no lineales de análisis numérico.
En general, un sistema con m ecuaciones lineales n incógnitas puede ser escrito en
forma ordinaria como:
mnmnm2m1
n
n
bxa+xa+xa
bxa+xa+xa
bxa+xa+xa
21
22n222121
11n212111
ΜΜΜΜΜΜ
Figura 4. Estructura de Sistema de Ecuaciones
Donde x1,…,xn son las incógnitas y los números aij K son los coeficientes del sistema
sobre el cuerpo K = R,C,… Es posible reescribir el sistema separando con coeficientes con
notación matricial:
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
bn
b2
b1
xn
x2
x1
amnamam
a2naa
a1naa
ΜΜ
Λ
ΜΜΜ
Λ
Λ
21
2221
1211
Figura 5. Reescritura de sistema de ecuaciones
Si representamos cada matriz con una única letra obtenemos: Ax = b.
30
2.3.3. Algoritmos de Solución de Ecuaciones Lineales
a. Métodos Directos
Se denomina Método Directo de resolución de Sistemas de Ecuaciones a todo aquel que
permite obtener la solución exacta, salvo errores de redondeo, de dicho sistema mediante
un numero finito de operaciones elementales (adición, sustracción, multiplicación, división y
extracción de raíces cuadradas) [18].
En los métodos directos no tiene importancia el criterio de convergencia como sí lo tiene
en los iterativos, además que no existe limitante al diseño de la matriz como en el caso de
los iterativos. A pesar de su alto costo computacional, los métodos directos son muy útiles
para resolver sistemas lineales dispersos ya que son generales y robustos. Hasta ahora son
muy pocos los avances que se han logrado en la implementación de métodos directos en
paralelo para matrices dispersas [19] si lo comparamos con los dados en los métodos
iterativos, en parte debido al alto costo de comunicaciones que pueden necesitar, más esto
no ha impedido que aun con estas limitantes existan opciones viables en la implementación
de algoritmos directos como por ejemplo la citada en [20].
Método de Eliminación Gaussiana
En forma general este método propone la eliminación progresiva de variables en el
sistema de ecuaciones, hasta tener sólo una ecuación con una incógnita, y consta de los
siguientes pasos:
1. Determinar la primera columna (a la izquierda) no cero.
2. Obtenga ceros abajo del elemento delantero sumando múltiplos adecuados a los
renglones debajo de abajo.
3. Repita el proceso comenzando en el paso 1. Al termino del ciclo entre el paso 1 al 4
(es decir cuando se han barrido todos los renglones), la matriz debería tener forma
escalonada.
4. Luego de esto, solo debe realizar la sustitución hacia atrás para obtener el valor de
todas las incógnitas.
31
b. Métodos Iterativos
Entre estos se encuentran los métodos de Jacobi y Gradiente Conjugado. El término
“método iterativo” hace referencia a un amplio conjunto de técnicas que, mediante la
realización de aproximaciones sucesivas, van obteniendo una estimación cada vez más
precisa de la solución de un determinado problema matemático. Estos métodos resultan
muy adecuados para la resolución de grandes sistemas de ecuaciones lineales, pudiendo
además ser paralelizados de manera más inmediata que los métodos directos.
Un elemento en contra que tienen los métodos iterativos sobre los métodos directos es
que calculan aproximaciones a la solución. Los métodos iterativos se usan cuando no se
conoce un método para obtener la solución en forma exacta, cuando el método para
determinar la solución exacta requiere mucho tiempo de cálculo, cuando una respuesta
aproximada es adecuada, y cuando el número de iteraciones es relativamente reducido.
Método de Jacobi
El método Jacobi es la primera opción en métodos iterativos para resolver sistemas de
ecuaciones lineales, por su sencillez y rapidez. Para su aplicación se hacen los siguientes
pasos
1. Primero se determina la variable theta: Si i es distinto de j entonces:
(1)
2. Se procede a calcular la siguiente aproximación de X
(2)
Y así sucesivamente durante X cantidad de iteraciones o hasta alcanzar la convergencia.
Cabe destacar que es un método efectivo si la matriz es diagonal dominante, mas puede
darse el caso de converger si no se cumple esta condición.
32
Método de Gradiente Conjugado
Explica [21] que la idea básica en del método del gradiente conjugado consiste en
construir una base de vectores ortogonales y utilizarla para realizar la búsqueda de la
solución. Una ventaja del método de gradiente conjugado radica en que cuando se utiliza
este procedimiento, basta con asegurar la ortogonalidad de un nuevo miembro con respecto
al último que se ha construido, para que automáticamente esta condición se cumpla con
respecto a todos los anteriores. La entrada al método será una elección de u0 como
condición inicial, ε > 0 como la tolerancia del método y N como el número máximo de
iteraciones. Este algoritmo sirve para resolver sistemas cuyas matrices son simétricas y
definidas positivas.
Su algoritmo viene dado por:
(3)
La salida del método será la solución aproximada x = (x1, ..., xN).
2.4. Formatos para almacenamiento de matrices
Como se indica en [22], en el mundo informático, los sistemas de ecuaciones lineales se
guardan en forma de matrices de tamaño n x m, y generalmente en la gran mayoría de los
casos prácticos, estas matrices son de gran tamaño, pero la mayoría de sus elementos son
ceros, y las cuales son llamadas de tipo dispersas.
33
Para ahorrar espacio y ancho de banda, se han creado diversos formatos para almacenar
estas matrices, cada uno de ellos con sus ventajas y desventajas. Se pueden dividir como
formatos generales o específicos, siendo éstos últimos típicamente a bloques. Cada formato
tendrá un rendimiento diferente dependiendo de las características de la matriz que se
almacene y la máquina en la que se ejecuten las operaciones, ya que arquitecturas
paralelas, vectorizadas y escalares pueden utilizar diferentes algoritmos para cada formato.
Entre los formatos más utilizados se encuentran el formato a coordenadas (COO),
Compressed Storage Row (CSR), Compressed Storage Column (CSC), Jagged Diagonal
Storage (JDS) y el Transpossed Jagged Diagonal Storage (TJDS).
2.4.1. Compressed Storage Row (CSR)
El formato Compressed Storage Row, o CSR, es una de los más populares para el uso de
matrices dispersas. Al ser un formato muy simple y compacto es muy adecuado para los
casos generales, debido a que no tiene ninguna característica que merme el rendimiento
especialmente.
Las matrices en el formato CSR se componen principalmente de 3 vectores: row_ptr,
col_ind y val. El vector row_ptr indica, para cada posición, el índice de los otros vectores en
los que empieza la fila. En la matriz de ejemplo, el primer valor es cero, puesto que la
primera fila empieza en la posición cero de los vectores. Para la segunda fila el valor es 2, ya
que la primera fila contiene 2 valores y el primer elemento de la segunda fila se encuentra
en ese índice de los otros dos vectores.
El último valor de row_ptr siempre apunta al primer valor fuera de rango. Los vectores
col_ind y val indican cada uno de ellos la columna y el valor de cada no-cero, de la misma
forma que se realiza en COO. Esta distribución es muy útil porque permite reducir el tamaño
del vector referente a las filas respecto COO, haciendo que la matriz ocupe menos espacio y
también permite un acceso directo y secuencial a cada una de las filas.
Suponga la siguiente matriz dispersa:
34
⎥⎥⎥⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢⎢⎢⎢
⎣
⎡
66650000
56550000
4645440420
003433031
025023220
001401211
aa
aa
aaaa
aaa
aaa
aaa
Figura 6. Matriz dispersa
Al transformarla a CSR, quedaría de la siguiente manera:
⎥⎥⎥⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢⎢⎢⎢
⎣
⎡
00006665
00005655
0046454442
000343331
000252322
000141211
aa
aa
aaaa
aaa
aaa
aaa
Figura 7. Representación de Compressed Storage Row
2.4.2. Compressed Storage Column (CSC)
El formato Compressed Storage Column (CSC) es exactamente igual al formato CSR, con
la única diferencia que, en vez de ordenar por filas, ordena por columnas. De este modo, se
tienen los vectores col_ptr, row_ind y val, completamente análogos a CSR.
El vector col_ptr indica el índice de los otros 2 vectores en los que empieza cada
columna, siendo el último elemento un índice a la primera posición fuera de rango. El vector
row_ind indica, para cada elemento, la fila en la que está situado, y val tiene el valor.
Si suponemos la matriz dispersa de la figura 6, su representación en formato
compressed storage column sería:
35
⎥⎥⎥⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢⎢⎢⎢
⎣
⎡
000000
000000
0650000
6655440420
564534332231
462514231211
a
aaaa
aaaaaa
aaaaaa
Figura 8. Representación de Compressed Storage Column
2.4.3. Jagged Diagonal Storage (JDS)
El formato Jagged Diagonal Storage (JDS), también nombrado JAD, abandona el
ordenamiento por filas en pro de un formato con vectores bidimensionales, dando más
estructura a la matriz, con sus ventajas e inconvenientes.
Por una parte, al tratar con los vectores bidimensionales se logra reducir el número de
estructuras necesarias para el formato, puesto que el valor de fila es parte intrínseca de la
estructura y no debe ser declarado en un vector aparte, como en los casos de CSR o COO.
El algoritmo para generar el formato JDS es el siguiente: A partir de una matriz A, se
desplazan todos los valores no-cero a la izquierda, resultando una matriz Acrs. En este
punto, se reordena la matriz por número de no-ceros por fila, quedando una matriz Ajds
cuyo número de no-ceros por columnas está en orden descendiente. Cada columna de la
matriz Ajds es una jagged diagonal.
Para almacenar esta matriz resultante se requieren 4 vectores: jd_ptr, col_ind, perm y
val. El vector jd_ptr tiene la misma función que row_ptr en CSR, e indica en qué posición de
los vector col_ind y val empieza cada jagged diagonal. Los vectores col_ind y val indican,
para cada elemento, la columna y el valor, respectivamente. El vector perm, de tamaño
número de filas, indica, para cada fila de la matriz Ajds, y por tanto, para cada elemento de
una jagged diagonal, la fila que corresponde en la matriz A original.
Si suponemos la matriz dispersa de la figura 2.5, su representación en formato Jagged
Diagonal Storage seria:
36
⎥⎥⎥⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢⎢⎢⎢
⎣
⎡
00006665
00005655
000343331
000252322
000141211
0046454442
aa
aa
aaa
aaa
aaa
aaaa
Figura 9. Representación de Jagged Diagonal Storage
2.4.4. Transposed Jagged Diagonal Storage (TJDS)
A partir del formato JDS se ha desarrollado una modificación llamada Transposed Jagged
Diagonal Storage (TJDS) cuya mayor diferencia respecto al JDS es que, en vez de realizar un
reordenamiento de las filas, lo realiza para las columnas.
En este caso, para una matriz A, desplaza todos los no-ceros hacia las primeras filas, de
forma vertical, dando lugar a una matriz Accs. Esta matriz resultante se reordena por
número de no-ceros por columna, siendo la primera columna la que tenga más no-ceros y la
última la que menos tenga. Esta matriz Atjds contiene, por filas, las trasposed jagged
diagonals.
El formato requiere sólo 3 vectores: tjd_ptr, row_ind y val. El funcionamiento es análogo
al JDS. tjd_ptr indica en qué posición de row_ind y val empieza cada transposed jagged
diagonal, y row_ind y val indican, para cada posición, la fila a la que pertenecen y el valor
correspondiente.
En este formato no se incluye un vector de permutación como en el JDS original ya que
se parte de que, al convertir la matriz al formato TJDS para una operación del tipo y=A·x,
también se convierte el vector x al formato (con el mismo reordenamiento con el que se
obtiene la matriz Atjds). Esto supone que una matriz en TJDS no se puede usar para más de
un vector de entrada. En la implementación realizada sí se incluye un vector de
permutación, de forma que antes de realizar la operación matricial, se reordena el vector x
para un correcto funcionamiento.
Si suponemos la matriz dispersa de la figura 2.5, su representación en formato
Transposed Jagged Diagonal Storage sería:
37
⎥⎥⎥⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢⎢⎢⎢
⎣
⎡
000000
000000
0000065
0066444255
333156342245
231146141225
a
aaaa
aaaaaa
aaaaaa
Figura 10. Representación de Transposed Jagged Diagonal Storage
CAPÍTULO III
MARCO METODOLÓGICO
En el presente capítulo se especifica el tipo y diseño de la investigación, así como los
procedimientos y técnicas que se utilizarán y desarrollarán durante la misma.
3.1. Tipo de investigación
La presente investigación se clasifica según los siguientes puntos de vista:
• Según su propósito, como una investigación aplicada, ya que se planifica con fines
prácticos y está orientada a resolver el problema asociado a la necesidad de
solucionar sistemas de ecuaciones lineales en entorno de computación distribuida.
Según [23], una investigación aplicada tiene como finalidad resolver un problema en
un período relativamente corto de tiempo.
• Según su objetivo, es de tipo proyectiva, ya que intenta proponer una solución a un
problema planteado. Según [24], este tipo de investigación implica explorar,
describir, explicar y proponer alternativas de cambio (transformación).
3.2. Metodología
La metodología empleada en esta investigación comprende las etapas descritas a
continuación.
3.2.1. Análisis de estructura de datos y método(s) de solución a utilizar
En esta fase se realiza una revisión de las diversas estructuras de datos que se podrían
aplicar a la librería, para luego proceder a seleccionar y codificar aquellas no existentes o
que no puedan obtenerse por licencia GPL. También en esta fase se decidirán el método o
los métodos de solución de ecuaciones lineales a utilizar.
39
3.2.2. Codificación de la librería
En esta fase se diseña, codifica y depura todas las clases necesarias para que la librería
realice sus funciones de manera correcta, utilizando el lenguaje Java y empleando técnicas
orientadas a objetos.
3.2.3. Diseño e Implementación de casos de estudio
En esta fase se realiza el análisis de casos de estudios formado por matrices que
representan sistemas de ecuaciones los cuales serán solucionados por la librería.
3.3. Herramientas y Equipos
A continuación se presenta una lista de herramientas y equipos a utilizar en la
elaboración de este trabajo.
3.3.1. Hardware
Para desarrollo del código y pruebas se utilizó el siguiente equipo de computación:
• Computador de escritorio con procesador Quad Core a 3 Ghz y 4 Gb de memoria
RAM.
Para pruebas también se utilizo el siguiente equipo cluster de computación:
• Cluster de 10 computadoras cada una con 2 procesadores AMD y enlazadas entre
ellas con una red Ethernet a 1000 Mb/s.
3.3.2. Software
Se empleará únicamente software con licencia de software libre y/o gratuito.
• Open JDK versión 6 con licencia GPL.
• IDE de desarrollo Netbeans.
• Librería IBIS.
CAPÍTULO IV
DISEÑO DE LA BIBLIOTECA
En el presente capítulo se explica cómo está diseñada la biblioteca, así como también las
estructuras de datos y algoritmos de solución que se utilizaron.
4.1. Biblioteca de paralelización
Para la comunicación paralela se utilizó la biblioteca IBIS, proyecto Java opensource para
aplicaciones en Grids y Clusters creada en la Universidad Vrije de Amsterdam, como modelo
de programación se utilizo GMI (Group Method Invocation).
4.2. Estructuras de datos utilizadas
Para la representación de las matrices se evaluaron los siguientes formatos:
• Compressed Storage Row (CSR)
• Compressed Storage Column (CSC)
• Jagged Diagonal Storage (JDS)
• Transposed Jagged Diagonal Storage (TJDS)
Luego de evaluar los distintos formatos, se eligió la estructura por columna transpuesta
(TJDS) para los métodos iterativos, que según [25], requiere un espacio reducido en
memoria, y estas estructuras requieren menos comunicación al momento de realizar la
multiplicación matriz por vector (Ax*b) ya que solo utilizan la porción de x y b
correspondiente a las columnas de cada proceso.
Para el algoritmo directo Eliminación Gaussiana, se decidió implementar una estructura
por filas, ya que al combinarla con un algoritmo asíncrono, demostró ser más eficiente a
efectos de sincronización y de procesamiento paralelo de los datos.
41
4.3. Predicción de posibles futuros valores no cero
Para el algoritmo de Eliminación Gaussiana, que por su naturaleza durante la ejecución
del algoritmo valores que solían ser ceros pueden dejar de serlo, además del alto costo de
inserción de nuevos valores en estructuras de datos para matrices dispersas, fue necesario
realizar un algoritmo de predicción de cuales valores tentativamente pueden dejar de ser
cero a lo largo del proceso, para que los mismos sean incluidos al momento de crear la
estructura de datos de la matriz, de esta manera el espacio de los mismos estaría reservado
en la estructura desde un principio ante un posible cambio de cero a algún valor.
Para esto, se procedió a codificar el método explicado en [26], con el cual se logró
obtener el resultado esperado, una matriz que abarca los posibles cambios de valores a lo
largo del cálculo.
4.4. Métodos de solución codificados
4.4.1. Gradiente Conjugado
Como se explico anteriormente, para este algoritmo se eligió una estructura por
columnas por encima de una estructura por filas, debido a que para la primera cada proceso
solo requiere su porción de los vectores b y x, reduciendo considerablemente la
comunicación necesaria al momento de envío o retorno / suma de datos.
Al comenzar el algoritmo se hace la división de la matriz A, vectores b y x, que son
enviados a sus respectivos procesos, quienes almacenan de forma local estos datos.
Luego de finalizado el proceso anterior, se comienza con el proceso de cálculo paralelo,
este algoritmo itera N veces hasta que alcanza la convergencia (norma de xk entre norma de
b < tolerancia deseada) o (si aplica, ya que suele ser opcional) llega a la cantidad de
iteraciones máximas asignadas por el usuario.
Para cada iteración se llaman a 4 métodos:
Multiplicación de matriz A por vector p: cada proceso recibe su parte del vector p, y
realiza la multiplicación, devolviendo su sub-vector respuesta, que son unidos por una
Respuesta Combinada (Combine Reply) del Ibis para obtener el vector final.
42
Calculo de valor alfa: Con el vector obtenido del método anterior, se procede a calcular
el escalar alfa, cada proceso recibe su parte del vector resultado A*p, y realiza el cálculo una
parte del mismo, que luego es sumado para obtener el valor final.
(4)
Calculo de nuevos vectores x, r, y cálculo de escalar beta (o Rho): En este método
se realizan 3 cálculos paralelos al mismo tiempo, se procede es a modificar la porcion de los
vectores x y r internos de cada proceso y a devolver el escalar beta para futuros
procesamientos. Cada procesador calcula su parte de beta, que luego es sumado al
resultado de los demás procesos para obtener el valor final.
(5)
Calculo de nuevo vector P y asignar nuevo beta (o Rho): Se procede a realizar el
cálculo del vector P, para lo cual se necesita el actual y nueva versión del escalar Rho, el
cual se calculo en el paso anterior y se le pasa como parámetro a este método. Luego de
calculado el vector P, se procede a reemplazar el Rho actual del procesador por el nuevo.
(6)
4.4.2. Jacobi
Al igual que para el algoritmo de Gradiente Conjugado, para este algoritmo se eligió una
estructura por columnas por encima de una estructura por filas, debido a que para la
primera cada proceso solo requiere su porción de los vectores b y x, reduciendo
considerablemente la comunicación necesaria al momento de envío o retorno / suma de
datos.
Al comenzar el algoritmo se hace la división de la matriz A, vectores b y x, que son
enviados a sus respectivos procesos, quienes almacenan de forma local estos datos.
43
Luego de finalizado el proceso anterior, se comienza con el proceso de cálculo paralelo,
este algoritmo itera N veces hasta que alcanza la convergencia (norma de xk entre norma
de b < tolerancia deseada) o (si aplica, ya que suele ser opcional) llega a la cantidad de
iteraciones máximas asignadas por el usuario.
Para este algoritmo, para cada iteración se llaman a 2 métodos:
Obtención de variable theta: cada procesador hace una multiplicación especial de
matriz A por vector x, especial ya que solo se usaran en la operación los valores distintos a
la diagonal, y el resultado se irá acumulando en la variable theta local de cada proceso, al
terminar, estas son unidas por una Respuesta Combinada (Combine Reply) del Ibis para
obtener la respuesta final.
(Cuando i es distinto de j) (7)
Calculo de aproximación de vector X(k+1): Ya que se tiene la variable final theta, esta
se envía a todos los procesos, para que calculen su porción local del vector X(k+1) mediante
la fórmula:
(8)
4.4.3. Eliminación Gaussiana
A diferencia de los algoritmos explicados anteriormente, para la Eliminación Gaussiana se
eligió una estructura por filas por encima de una estructura por columnas, ya que por la
naturaleza del algoritmo se debe comunicar toda la fila que ya paso por el procedimiento de
“división”, y para efectos de obtener el mejor tiempo, esta comunicación se hace de forma
asíncrona.
El algoritmo consiste en k iteraciones donde k es la cantidad de filas totales de la matriz.
Cada iteración consiste de dos fases, fase de división y fase de eliminación.
En la implementación paralela divide la matriz entre los procesos participantes,
asignándole a cada uno un k/p número de filas.
44
Fase de división: no es paralelizable, cada proceso evalúa si la fila a dividir le
pertenece, y si este es el caso hace la división y envía asíncronamente a los demás proceso
la fila modificada para puedan realizar la fase de eliminación. Si el proceso no posee la fila a
dividir, el mismo se pone a espera de datos.
Fase de eliminación: Cuando cada proceso ha recibido la fila k producto de la fase de
división procede a la fase de eliminación, que consiste en llevar a cero los valores de la
columna k debajo de la fila k. Esta fase se realiza paralelamente, si un proceso determina
que posee un valor distinto de 0 en la columna k debajo de A(k,k) entonces suma esa fila a un
múltiplo de la fila k que haga 0 ese valor.
CAPÍTULO V
CASOS DE ESTUDIO Y RESULTADOS
En el presente capítulo se explica los casos de estudio utilizados, así como los tiempos de
procesamiento de cada una de las matrices que componen los mismos.
5.1. Casos de estudio
Se seleccionaron algunas matrices para ser resueltas por cada uno de los algoritmos
codificados, diferenciadas por su tamaño: de pequeña, mediana y grandes dimensiones. Las
mismas fueron extraídas de University of Florida’s Sparse Matrix Collection [27], un
repositorio de matrices disponibles al público para casos de investigación:
Para el algoritmo directo Eliminación Gaussiana
• C-19: Matriz de 2327x2327, con 4003366 valores (después de predicción).
• Add20: Matriz de 2395x2395, con 4740941 valores (después de predicción).
Para los algoritmos Iterativos
• ND3K: Matriz de 9000x9000, con 1644345 valores.
• ND6K: Matriz de 18000x18000, con 3457658 valores.
Para los algoritmos de Eliminación Gaussiana, los archivos planos de las matrices poseen
más valores, ya que se están incluyendo las predicciones necesarias para el correcto
funcionamiento de los mismos.
5.2. Métricas de medición de desempeño
5.2.1. SpeedUp
Según [28], en los algoritmos paralelos, el tiempo no es la suma de los tiempos de la
CPU en cada procesador. La opción más prudente para medir el rendimiento es el tiempo
46
real. El SpeedUp compara tiempo serial con tiempo paralelo para resolver un problema en
particular. Para los algoritmos no deterministas, SpeedUp compara el tiempo de la ejecución
serial principal con el tiempo de ejecución principal paralelo. Las metaheurísticas son
algoritmos típicamente no determinista y pueden producir diferentes resultados al ser
ejecutados varias veces aun teniendo la misma configuración.
El SpeedUp se calcula a través de la siguiente razón:
mT
T=mS 1 (9)
Donde Tm es el tiempo de ejecución de un algoritmo usando m procesadores y T1 es el
tiempo de ejecución del algoritmo usando un procesador. Con estas definiciones se pueden
distinguir SpeedUp lineal (Sm=m) sublineal (Sm<m) y SpeedUp superlineal (Sm>m).
5.2.2. Eficiencia
La eficiencia está relacionada con el SpeedUp, normaliza su valor teniendo en cuenta el
número de procesadores [17]:
mmS
=mE (10)
Donde Em=1 significa SpeedUp lineal. Esta métrica representa el grado de
aprovechamiento de los procesadores para la resolución del problema. El valor máximo que
puede alcanzar es 1, que significa un 100% de aprovechamiento. Explica [18] que la
Eficiencia resulta una métrica de calidad y de costo del algoritmo paralelo que es
particularmente importante y no siempre se puede mantener al escalar los problemas, al
incrementar el número de procesadores o al portar el algoritmo sobre otra arquitectura
multiprocesador.
5.3. Hardware utilizado en las pruebas
Para realizar las pruebas, se utilizaron los siguientes equipos de hardware:
47
• Cluster de 10 computadoras doble núcleo con 1gb de memoria RAM, ubicado en el
Instituto de Calculo Aplicado (ICA) de la Universidad del Zulia, el cual será
identificado como GOD.
• Computador Quad-Core con 4gb de memoria RAM, el cual será identificado como
SER.
5.4. Algoritmo Gradiente Conjugado
a. Pruebas con GOD
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 1. Tiempo en segundos de ejecución Gradiente Conjugado en GOD
Matriz / Cores 1 2 4 6 8
ND3K 230,36 149,09 102,70 93,99 107,19
ND6K 408,80 357,58 225,82 191,15 227,18
Figura 11. Speed Up Gradiente Conjugado en GOD
48
Figura 12. Eficiencia Gradiente Conjugado en GOD
b. Pruebas con SER
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 2. Tiempo en segundos de ejecución Gradiente Conjugado en SER
Matriz / Cores 1 2 4
ND3K 138,61 88,49 55,34
ND6K 291,65 178,34 114,38
Figura 13. Speed Up Gradiente Conjugado en SER
49
Figura 14. Eficiencia Gradiente Conjugado en SER
5.5. Algoritmo Jacobi
a. Pruebas con GOD
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 3. Tiempo en segundos de ejecución Jacobi en GOD
Matriz / Cores 1 2 4 6 8
ND3K 19,82 14,114 8,2806 6,38 7,983
ND6K 100 55,86 37,149 27,8123 32,11
Figura 15. Speed Up Jacobi en GOD
50
Figura 16. Eficiencia Jacobi en GOD
b. Pruebas con SER
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 4. Tiempo en segundos de ejecución Jacobi en SER
Matriz / Cores 1 2 4
ND3K 14,12 7,517 4,64
ND6K 64,4 35,42 19,15
Figura 17. Speed Up Jacobi en SER
51
Figura 18. Eficiencia Jacobi en SER
5.6. Algoritmo Eliminación Gaussiana
a. Pruebas con GOD
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 5. Tiempo en segundos de ejecución Eliminación Gaussiana en GOD
Matriz / Cores 1 2 4 6 8 10
C-19 337,87 282,58 118,88 92,93 86,84 94,73
Add20 286,35 180,03 104,186 91 82,06 104,93
Figura 19. Speed Up Eliminación Gaussiana en GOD
52
Figura 20. Eficiencia Eliminación Gaussiana en GOD
b. Pruebas con SER
A continuación se detallan los resultados y métricas de las pruebas realizadas.
Tabla 6. Tiempo en segundos de ejecución Eliminación Gaussiana en SER
Matriz / Cores 1 2 4
C-19 211,9 117,75 85,7
Add20 176,18 107,28 80,69
Figura 21. Speed Up Eliminación Gaussiana en SER
53
Figura 22. Eficiencia Eliminación Gaussiana en SER
CONCLUSIONES
Como se pudo observar en las pruebas realizadas, y tal como se explicó en el marco
teórico, los algoritmos iterativos son los más rápidos y eficientes en cuanto a velocidad, mas
están limitado a cierto diseño y estructura de matrices, como que sean diagonalmente
dominantes como el caso de Jacobi, o positiva definida en el caso del Gradiente Conjugado,
además que los mismos no necesitan un algoritmo de predicción para cambios en los valores
que son cero al iniciar el proceso.
Es observable que el SpeedUp aumenta a medida que las matrices o datos de entrada
sean más grandes, lo cual es totalmente lógico ya que la paralelización comienza a ser un
método necesario y eficiente es al aumentar la cantidad de procesamiento necesario para la
solución de un problema.
También durante la realización de la investigación, se pudo conocer que existen
algoritmos mas paralelizables que otros, como por ejemplo Jacobi, donde en un inicio los
datos son enviados a los procesadores y solo debe haber una mínima comunicación entre
ellos, cosa que no sucede en Eliminación Gaussiana y Gradiente Conjugado, donde debe
existir mas comunicación entre los procesadores, lo que aumenta el tiempo de ejecución,
sobre todo en computadoras con memoria distribuida, ya que, a diferencia de aquellas con
memoria compartida, el desempeño se ve mucho más afectado debido a la latencia de la
red.
RECOMENDACIONES
Como recomendaciones, se pueden indicar:
• Codificar más algoritmos de resolución, así como continuar investigando nuevas
formas de paralelizar los existentes.
• Codificar los algoritmos con otras librerías paralelas distintas a IBIS GMI que quizás
podrían llegar a ser más eficientes.
BIBLIOGRAFÍA
[1] PETSc (Portable, Extensible Toolkit for Scientific Computation) Website.
http://www.mcs.anl.gov/petsc/
[2] IMSL® Numerical Libraries Website.
http://www.roguewave.com/products/imsl-numerical-libraries.aspx
[3] Michael Thomas Flanagan's Java Scientific Library Website.
http://www.ee.ucl.ac.uk/~mflanaga/java/
[4] JAMPACK, A java package for matrix computations website.
ftp://math.nist.gov/pub/Jampack/Jampack/AboutJampack.html
[5] Matrix Toolkit for Java Website.
http://code.google.com/p/matrix-toolkits-java/
[6] Ibis Project Website. http://www.cs.vu.nl/ibis/index.html
[7] García de Jalon J., Rodríguez J., Mingo I., Imaz A., Brazález A., Larzabal A.,
Calleja J., García J. (2000). Aprenda Java como si estuviera en primero.
[8] Giménez D., Boratto M., Coelho L. (2009). Programación Paralela y Distribuida.
[9] Google's data centers Website.
http://www.google.com/about/datacenters/
[10] Seti@Home Website. http://setiathome.berkeley.edu/
[11] Stallings W. (2010). Computer Organization and Architecture, Seventh Edition.
[12] Guiness World Record Website – First dual core smartphone.
http://www.guinnessworldrecords.com/records-9000/first-dual-core-smartphone/
57
[13] Blaise B., Parallel Computation. Lawrence Livermore National Laboratory
https://computing.llnl.gov/tutorials/parallel_comp
[14] Flynn, M., (1972). Some Computer Organizations and Their Effectiveness, IEEE Trans.
Comput., Vol. C-21.
[15] Maasen J., Kielmann T., Bal H. (2003). GMI: Flexible and Efficient Group Method
Invocation for Parallel Programming. Division of Mathematics and Computer Science, Vrije
Universiteit, Amsterdam.
[16] Enciclopedia Britannica. Hombre, Ciencia y Tecnología (1995). Ediciones Océano
S.A.
[17] García-Pelayo R. (1978). Enciclopedia de las Ciencias Larousse, Volumen 1. Librairie
Larousse.
[18] Jaramillo J., Vidal A., Correa F. (Febrero 2006) Métodos Directos para la solución de
sistemas de ecuaciones lineales simétricos, indefinidos, dispersos y de gran dimensión.
[19] Lázaro C., Winter Althaus G. (1990) Métodos y algoritmos básicos del álgebra
numérica.
[20] Xiaofang W., Sotirios Z. Parallel Direct Solution of Linear Equations on FPGA-Based
Machines. New Jersey Institute of Technology.
[21] Herrera Revilla I. (sin fecha). Un Análisis del Método de Gradiente Conjugado.
[22] Pasarín M., Otero B., Herrero J. Estudio y evaluación de formatos de
almacenamiento para matrices dispersas en arquitectura multi-core.
[23] Chávez Alizo, N. (1994). Introducción a la investigación educativa. Editorial Gráfica,
Caracas.
[24] Hurtado de Barrera, J. (2008). Cómo formular objetivos en investigación. Ediciones
Quirón-Sypal, Caracas, 2da edición edition.
58
[25] Ekambaram A, Montagne E. (2003). An Alternative Compressed Storage Format for
Sparse Matrices. ISCIS 2003, LNCS 2869, paginas 196–203.
[26] George A., Ng E. Symbolic Factorization for Sparse Gaussian Elimination with Partial
Pivoting. 1984.
[27] University of Florida’s Sparse Matrix Collection Website.
http://www.cise.ufl.edu/research/sparse/matrices/
[28] García A., Luque G., Alba E. (2011). Influencia de las métricas paralelas en el análisis
de algoritmos paralelos metaheurísticos. Serie Científica de la Universidad de las Ciencias
Informáticas. No. 4, Vol. 4.
• Otras bibliografías utilizadas.
Expósito Singh D. Gradiente Conjugado en Multiprocesadores de Memoria Compartida.
Master’s thesis, Universidad de Santiago de Compostela.
Sanz V., Chichizola F., M. Naiouf. Superlinealidad sobre clusters. (2007) Análisis
experimental en el problema del puzzle n2 -1. Instituto de Investigación en Informática (III-
LIDI), Facultad de Informática, UNLP.
Shahnaz R., Usman A. (2007) An Efficient Sparse Matrix-Vector Multiplication on
Distributed Memory Parallel Computers.
Shahnaz R., Usman A., Imran C. (2006) Implementation and Evaluation of Parallel Sparse
Matrix-Vector Products on Distributed Memory Parallel Computers. IEEE.
Riyavong S. (2003). Experiments on Parallel Matrix-Vector Product.
De la Fuente, J. (1997). Técnicas de Cálculo para Sistemas de Ecuaciones, Programación
Lineal y Programación Entera. Universidad Politécnica de Madrid.