IMPLEMENTACIÓN DE CLUSTER DE COMPUTADORAS PARA APLICACIONES DE INGENIERÍA. AUTORES CUEVAS VALENCIA, RENÉ EDMUNDO FELICIANO MORALES, SEVERINO MOLINA ÁNGEL, FÉLIX Responsable de la publicación digital: M en C. Félix Molina Ángel. Gestión del ISBN: RENE EDMUNDO CUEVAS VALENCIA. Diseño de portada: René Edmundo Cuevas Valencia. Responsables de la Reproducción en Discos Compactos: Cuevas Valencia René Edmundo. Financiamiento para la Reproducción del EBook: M. en C. Juan Carlos Medina Martínez, Director de la U A de Ingeniería. Sitio WEB: http://ingenieria.uagro.mx/catics ISBN: 978-­‐607-­‐00-­‐3902-­‐7 El contenido de este EBook, es con fines educativos que impacten en el programa de Ingeniero en Computación de la UAI de la UAGro. Se permite la reproducción total o parcial del mismo por cualquier medio, siempre y cuando se cite a los autores. Chilpancingo de los Bravo, Guerrero, México. Diciembre de 2010. CONTENIDO CONTENIDO Pág. 1 INTRODUCCIÓN 1. DESCRIPCIÓN DE LOS CLUSTER 1.2. Características de los cluster 1.3. Tipos de acoplamiento en un cluster 1.4. Esquema y otras características 1.4.1. El factor de control del cluster 1.4.2. Seguridad 1.4.3. Homogeneidad 1.4.3.1. Homogeneidad de un cluster 1.5. Clasificación de los cluster 1.5.1. Alto rendimiento (HP High Performance) 1.5.1.1. Problemas que solucionan 1.5.1.2. Técnicas que utilizan 1.5.2. Alta disponibilidad (HA High Availability) 1.5.2.1. Problemas que solucionan 1.5.2.2. Técnicas que utilizan 1.5.3. Alta confiabilidad (HR High Reliability) 1.6. Tecnologías similares a cluster tipo Beowulf 1.7. Estado del arte 2. CLUSTER DE APLICACIÓN 2.1. Conceptos de Migración y Balanceo 2.1.2. PVM (Parallel Virtual Machine) y MPI (Message Passing Interface) 2.1.3. Paso de mensajes 2.2. PVM 2.3. MPI 2.4. Beowulf 2.5. OpenMosix 3. CLUSTER DE SISTEMA 3.1. Introducción 3.2. Mainframes, Supercomputadoras y Cluster 3.3. De MOSIX a openMosix 3.3.1. Características de openMosix 3.3.2. Algoritmo de migración 3.3.3. El nodo raíz 3.3.4. El mecanismo de migración 3.3.5. ¿Cuándo podrá migrar un proceso? 3.3.6. La comunicación entre usuario y kernel 3.3.7. Instalación de un cluster openMosix 3.3.8. Instalación del kernel de openMosix 3.3.8.1. Opciones del kernel de openMosix 3.4. Administración del cluster 3.4.1. Administración básica 3.4.2 Configuración ! "! 2 4 7 10 10 11 11 11 12 12 13 13 14 14 15 15 16 16 ! #$! #$! %&! %'! %(! %$! )*! )*! ! )%! )%! ))! ))! ))! )'! )'! )(! )(! )(! )+! )+! )$! &)! &)! &)! CONTENIDO 3.4.3. Las herramientas de área de usuario 3.4.4. Detección automática de nodos 3.4.5. Compilaciones 3.4.6. Problemas 3.5. Testeo de rendimiento con Stress-Test 3.5.1. Descripción general 3.5.2. Descripción detallada 3.5.3. openMosixview 3.5.3.1. Instalación 3.5.3.2. Instalación desde paquetes RPM 3.5.3.3. Instalación desde las fuentes 3.5.3.4. Script de configuración automático 3.5.3.5. Compilación manual 3.6. Utilizando openMosixview 3.6.1. Aplicación principal 3.6.2. La ventana de configuración 3.6.3. Ejecución avanzada 3.6.4. La línea de comandos 3.6.4.1. El host-chooser 3.6.4.2. El host-chooser paralelo 3.6.5. openMosixprocs 3.6.5.1. La ventana de migración 3.6.5.2. Administrando procesos remotamente 3.6.6. openMosixcollector 3.6.7. openMosixanalyzer 3.6.7.1. Una visión general de la carga del sistema 3.6.7.2. Estadísticas sobre los nodos del cluster 3.6.7.3. Monitorización de la memoria 3.6.7.4. openMosixhistory 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERÍA. 4.1. Hardware requerido 4.2. Software utilizado 4.3. Herramientas que se utilizan en los cluster 4.3.1. Información general sobre Software Libre 4.3.2. Herramientas de software / Software tools (Windows 98/XP y LINUX) 4.4. Estructura interna de un archivo tipo POV 4.4.1. Estructura interna de un archivo tipo INI 5. ANÁLISIS DE RESULTADOS 5.1. Resultados obtenidos de una sola computadora 5.1.1. Categoría: advanced 5.1.2. Categoría: animation 5.2. Resultados obtenidos utilizando el cluster 5.2.1 Categoría: advanced 5.2.2. Categoría: animation 5.3. Ejecución múltiple usando cluster 5.3.1. Categoría: Advanced 5.3.2. Categoría: animation ! ""! &'! &,! &$! &$! '*! '*! '*! '*! '*! '#! '#! '#! '#! '%! '%! ')! '&! ''! '(! '(! '(! '(! '+! '+! '$! '$! (*! (*! (#! ! (%! (%! ()! (&! ('! ('! ($! ,*! ! ,#! ,#! ,#! ,&! +#! +%! ++! $,! $,! #*%! CONTENIDO 5.4. Análisis de resultados 5.4.1. Ejecución sin utilización del cluster 5.4.2. Ejecución utilizando el cluster ANEXO 1. Glosario de Términos ANEXO 2. Errores más frecuentes al compilar e instalar el kernel ANEXO 3. Instalación de las herramientas de área de usuario ANEXO 4. Errores frecuentes en la compilación e instalación de las herramientas ANEXO 5. Configurando la topología del cluster ANEXO 6 Las herramientas de área de usuario ANEXO 7 Optimizando el cluster ANEXO 8 Descripción detallada Stress-Test ANEXO 9 abyss.pov ANEXO 10 chess2.pov ANEXO 11 grenadine.pov ANEXO 12 landscape.pov ANEXO 13 camera2.pov, camera2.ini ANEXO 14 float4.pov, float4.ini ANEXO 15 vect1.pov, vect1.ini ! ! """! #*+! #*+! #*$! ! ###! ##$! #%*! #%#! #%%! #%(! #)%! #)&! #)(! #&+! #'+! #(*! #((! #($! #,#! ! ! INTRODUCCIÓN. INTRODUCCIÓN El presente libro gira en torno a la investigación de los Cluster usando la tecnología Beowulf y manipulando el sistema operativo Linux en su distribución Red Hat versión 9.0, realizando las modificaciones necesarias en el Kernel para trabajar con OpenMosix, para lograr con ello un proceso paralelo de tareas cada vez que se ejecute alguna aplicación, analizándose aplicaciones de ingenieria para posteriormente proporcionar resultados, realizando cuadros comparativos en base a tiempo maquina y destacando la importancia de compartir tareas con n equipos de computo para la obtención de resultados en tiempos cortos. Así también se describen los tipos de clusters de aplicación que se manejan, proporcionando características que los diferencian; agregando los pasos a seguir para tener una adecuada instalación y configuración de un cluster de sistema. Con todo lo anterior se logrará presentar un análisis de las aplicaciones de ingenieria que se utilizaron para desarrollar este trabajo. El presente libro se inscribe en el marco de la investigación experimental en el área de los Sistemas Distribuidos; donde se instalará, programará y experimentará con diversos sistemas que fueron pensados para resolver problemas complejos que involucran tiempos de demora y que se pretende optimizar su desempeño bajo el uso de los clusters de alto rendimiento. Los cambios que se observan en el Hardware, han motivado pensar que los equipos que se adquieren en un futuro relativamente corto tal Hardware será obsoleto; ya que la presencia de nuevos programas (Software) hacen necesario tener mayores requerimientos y en su defecto reemplazarlos por otro equipo con características superiores. La necesidad de estar a la vanguardia referente al Hardware lleva a las Instituciones Educativas a destinar parte de su presupuesto para la adquisición de equipos de cómputo más sofisticados, considerando los escasos recursos económicos con los que se cuenta en las Instituciones Públicas, es necesario implementar estrategias para la reutilización de la infraestructura de Hardware existente. Muchas aplicaciones en el área de las Ciencias de la Computación requieren de la ejecución de programas en tiempos cortos, esto lleva a que cada día se tenga que dar soluciones a distintas áreas del conocimiento de la ingenieria. La implementación de clusters es una solución que ayuda en gran medida a optimizar los recursos que se tienen y explotarlos al máximo, ya que su objetivo es el de dividir el problema en tareas para darle solución en menor tiempo. Es por ello que se pretende explicar la instalación de un cluster y buscar entre distintas aplicaciones alguna que permita demostrar el rendimiento y potencial que se tendría en una institución educativa de nivel superior, vinculándose con las materias afines, con el objeto de darle un uso práctico para los programas de estudio de licenciatura y postgrado. 1 1. DESCRIPCIÓN DE LOS CLUSTER 1. DESCRIPCIÓN DE LOS CLUSTER Al principio las necesidades de las empresas e instituciones eran cubiertas con el uso de una computadora personal, conforme se fue avanzando y explotando los recursos tanto de Hardware como de Software, se empezaron a tener otras necesidades como la comunicación entre computadoras, con ello nace y se desarrollan las Redes de computadoras de forma local y a medida que se requería comunicarse a grandes distancias se desarrollaron las redes en toda la extensión, dando paso a la evolución del Internet con los alcances que ya conocemos. A medida que crece la necesidad de estar comunicados, también evolucionan las distintas áreas de la investigación científica, educativa, médica, etc; esto conlleva al desarrollo de programas ó software diseñados a la medida para resolver problemas específicos obteniendo al máximo los requerimientos físicos del equipo y adaptándose a los lenguajes de programación que existan en el momento. La potencialidad del Hardware no ha dejado de crecer, esto es resultado de las necesidades y demandas de los usuarios para lograr mayor capacidad de procesamiento (esto ayuda a ejecutar las operaciones de los programas en un tiempo menor), de almacenamiento temporal (que se usa para que coordinadamente con el procesador pueda realizar con mayor rapidez las tareas solicitadas), de almacenamiento secundario (el cual aumenta en proporciones gigantescas, ya que la necesidad de guardar volúmenes de información de forma permanente se vuelve una prioridad en cualquier área) y de comunicación usando la red (comunicarse al mundo exterior o simplemente compartir la información que se tiene de una computadora a otra). La necesidad de reutilizar equipos de cómputo ha dado paso a que distintas áreas del conocimiento ó computo evolucionen, una de ellas es el proceso distribuido, la necesidad de implementar programas que se puedan ejecutar en distintas computadoras. La programación seriada y la programación paralela han logrado que se generen aplicaciones aportando beneficios significativos al mundo de la computación. La necesidad de comunicarse a través de computadoras unidas por una red de comunicación para realizar un trabajo, esto puede ser el resultado de obtener alta disponibilidad, alto rendimiento, en aplicaciones que por si solas consumirían tiempos considerables. Una solución a estas necesidades es la implementación de clusters de computadoras. Un cluster es un grupo de equipos independientes que ejecutan una serie de aplicaciones de forma conjunta y se muestran ante clientes y aplicaciones como un solo sistema. Existen diversas interpretaciones para definir un cluster, a continuación se citan solo algunas definiciones: 2 1. DESCRIPCIÓN DE LOS CLUSTER “Un cluster consiste en un conjunto de computadoras y un servidor de cluster dedicado, para realizarlos relativamente infrecuentes accesos a los recursos de otros procesos, se accede al servidor de cluster de cada grupo.” (Silberschatz & Galván, 2003). “Un cluster es la variación de bajo precio de un multiprocesador masivamente paralelo (miles de procesadores, memoria distribuida, red de baja latencia), con las siguientes diferencias: cada nodo es una computadora quizás sin algo del hardware (monitor, teclado, mouse, etc.), el nodo podría ser SMP. Los nodos se conectan por una red de bajo precio como Ethernet o ATM aunque en cluster comerciales se pueden usar tecnologías de red propias. El interfaz de red no está muy acoplado al bus I/O. Los nodos tienen disco local. Cada nodo tiene un sistema operativo UNIX con una capa de software para soportar todas las características del cluster.” (Hwang & Xu,1998). “Es una clase de arquitectura de computador paralelo que se basa en unir computadoras independientes cooperativas integradas por medio de redes de interconexión para proveer un sistema coordinado, capaz de procesar una carga.” (Sterling, 2001). En 1994 Thomas Sterling y Don Becker, bajo el patrocinio del proyecto ESS del Centro de la Excelencia en Ciencias de los Datos y de la Información del Espacio (CESDIS) construyeron el primer Cluster de Computadoras el cual llamaron Beowulf con fines de investigación. Beowulf no es un paquete de Software especial, no es una topología de red diferente, tampoco un núcleo modificado. Beowulf es una tecnología que permite agrupar computadoras basadas en el sistema operativo Linux para formar una supercomputadora virtual paralela. Figura 1.1. Figura 1.1. Representación de un Cluster Beowulf Beowulf esta basada en multicomputadoras el cual puede ser utilizado para la computación paralela. Este sistema consiste de un nodo maestro y uno o más nodos esclavos conectados a través de una red Ethernet u otra topología de red. Está construido con componentes de Hardware comunes, solo debe tener la capacidad de ejecutar el sistema operativo Linux, así como también contar con tarjetas de red Ethernet y switches estándares. Como no cuenta con elementos de Hardware especiales, resulta totalmente reproducible. 3 1. DESCRIPCIÓN DE LOS CLUSTER Una de las diferencias más significativas entre un cluster Beowulf y un COW (Cluster Of Workstations, Cluster de estaciones de trabajo) es el hecho de que un Beowulf se comporta como una sola computadora y el COW como muchas estaciones de trabajo conectadas y en la mayoría de los casos los nodos esclavos no tienen monitores o teclados y son accesados de forma remota o por una terminal serial; donde el nodo maestro controla el cluster entero y presta servicios de sistemas de archivos a los nodos esclavos, es también la consola del cluster y la conexión hacia el exterior. Las computadoras grandes de Beowulf pueden tener más de un nodo maestro y otros nodos dedicados a diversas tareas específicas como por ejemplo consolas o estaciones de supervisión. En la mayoría de los casos los nodos esclavos de un sistema Beowulf son estaciones simples. Los nodos son configurados y controlados por el nodo maestro y hacen solamente lo que éste le indique. En una configuración de esclavos sin disco duro, estos incluso no saben su dirección IP hasta que el maestro les dice cuál es. La topología de red recomendada es de tipo Bus, debido a la facilidad para proporcionar escalabilidad a la hora de agregar nuevos nodos al cluster. Protocolos como Ethernet, Fast Ethernet, Giga Ethernet, 10/100 Mbps, Switch Ethernet, son tecnologías consideradas apropiadas para ser utilizadas en Beowulf. Beowulf utiliza como sistema operativo cualquier distribución Linux. La distribución en la cual se han realizado más trabajos Beowulf es con la conocida como Red Hat en cualquiera de sus versiones existentes. Sin lugar a duda los cluster presenta una alternativa importante para diversos problemas particulares, no solo por su economía, sino también porque pueden ser diseñados y ajustados para aplicaciones específicas (Beowulf,2003). 1.2. Características de los cluster Para crear un cluster se necesitan al menos dos nodos. Una de las características principales de estas arquitecturas es que exista un medio de comunicación (red) donde los procesos puedan migrar para computarse en diferentes estaciones paralelamente. Un solo nodo no cumple este requerimiento por su condición de aislamiento para poder compartir información. Las arquitecturas con distintos procesadores en una sola tarjeta madre tampoco se consideran cluster, bien sean computadoras SMP (multiprocesamiento simétrico) o Mainframes, debido a que el bus de comunicación no puede ser de red, sino interno. Los cluster permiten aumentar la escalabilidad, disponibilidad y fiabilidad de múltiples niveles de red. 4 1. DESCRIPCIÓN DE LOS CLUSTER La escalabilidad es la capacidad de un equipo para hacer frente a volúmenes de trabajo cada vez mayores sin, por ello, dejar de prestar un nivel de rendimiento aceptable. Existen dos tipos de escalabilidad: a) Escalabilidad del Hardware: denominada “escalamiento vertical”. Se basa en la utilización de un gran equipo cuya capacidad se aumenta a medida que lo exige la carga de trabajo existente. b) Escalabilidad del Software: denominada “escalamiento horizontal”. Se basa, en la utilización de un cluster compuesto de diversos equipos de mediana potencia que funcionan de forma muy parecida a como lo hacen las unidades de un RAID (Arreglo Redundante de Discos de Bajo Costo). Se utiliza el término RAC (Arreglo Redundante de Equipos) para referirse a los cluster de escalamiento horizontal. Del mismo modo que se añaden discos a un arreglo RAID para aumentar su rendimiento, se pueden añadir nodos a un cluster para aumentar también su rendimiento. La disponibilidad y la fiabilidad son dos conceptos que, si bien se encuentran íntimamente relacionados, difieren ligeramente. La disponibilidad es la calidad de estar presente, listo para su uso, a mano, accesible; mientras que la fiabilidad es la probabilidad de un funcionamiento correcto. Los fabricantes de Hardware intentan anticiparse a las fallas aplicando la redundancia en áreas clave como son las unidades de disco, las fuentes de alimentación, las tarjetas controladoras de red y los ventiladores, pero dicha redundancia no protege a los usuarios de las fallas de las aplicaciones. De poco serviría, por lo tanto, que un servidor sea confiable si el software de base de datos que se ejecuta en dicho servidor falla, ya que el resultado no seria otro que la ausencia de disponibilidad. Esa es la razón de que un solo equipo no pueda ofrecer los niveles de escalabilidad, disponibilidad y fiabilidad necesarios que sí ofrece un cluster. Una de las herramientas de auge en la actualidad son los llamados cluster Beowulf, los cuales presentan diversas capacidades para el computo paralelo con un relativo alto rendimiento. Por consiguiente se describen las tres características de un cluster: ! Consta de 2 o más nodos. ! Los nodos de un cluster están conectados entre sí por al menos un canal de comunicación. ! Los cluster necesitan software de control especializado. El problema también se plantea por los distintos tipos de cluster, cada uno de ellos requiere un modelado y diseño del Software distinto. Las características del cluster son completamente dependientes del Software, parte de este software se debe dedicar a la comunicación entre los nodos. Existen diferentes tipos de software que pueden conformar un cluster: 5 1. DESCRIPCIÓN DE LOS CLUSTER A. Software a nivel de aplicación. Situado a nivel de aplicación, se utilizan generalmente bibliotecas de carácter general que permiten la abstracción de un nodo a un sistema conjunto, permitiendo crear aplicaciones en un entorno distribuido de manera lo más abstracta posible. Este tipo de software genera elementos de proceso del tipo rutinas, procesos o tareas, que se ejecutan en cada nodo del cluster y se comunican entre sí a través de la red. Figura 1.2. B. Software a nivel de sistema. Situado a nivel de sistema, esta implementado como parte del sistema operativo de cada nodo, o ser la totalidad de éste. Es más crítico y complejo, por otro lado resuelve problemas de carácter más general que los anteriores y su eficiencia, es mayor. Figura 1.3. A pesar de esta división existen casos de implementaciones híbridas donde un cluster puede tener implementado a nivel de Kernel como parte del sistema y otra parte estar preparada a nivel de usuario. Para establecer las diferencias entre los distintos tipos de sistemas Beowulf se presenta la siguiente clasificación. Clase I. Son sistemas compuestos por computadoras cuyos componentes cumplen con la prueba de certificación “Computer Shopper” lo que significa que sus elementos son de uso común, y pueden ser adquiridos muy fácilmente en cualquier tienda distribuidora. De esta manera, estos cluster no están diseñados para ningún uso ni requerimientos en particular. Figura 1.2. Cluster a nivel de aplicación 6 1. DESCRIPCIÓN DE LOS CLUSTER Figura 1.3. Cluster a nivel de sistema Clase II. Son sistemas compuestos por computadoras cuyos componentes no pasan la prueba de certificación “Computer Shopper” lo que significa que sus componentes no son de uso común y por tanto no pueden encontrarse con la misma facilidad que los componentes de sistemas de la clase anterior. De tal manera, pueden estar diseñados para algún uso o requerimiento en particular. Las computadoras ubicadas en esta categoría pueden presentar un nivel de prestaciones superior a las de la clase I (miKel & Buytaert, 2004). 1.3. Tipos de acoplamiento en un cluster Dependiendo del tipo de software, el sistema puede estar más o menos acoplado. Se entiende por acoplamiento del software a la integración que tengan los elementos software que existan en cada nodo. Gran parte de la integración del sistema la produce la comunicación entre los nodos y es por esta razón por la que se define el acoplamiento; otra parte es la que implica que tan crítico es el software y su capacidad de recuperación ante fallas. Es importante mencionar que depende que el sistema se encuentre centralizado o distribuido. En cualquiera de los dos casos el acoplamiento es una medida subjetiva basada en la integración de un sistema a nivel general de cluster. Se distinguen entre 3 tipos de acoplamiento: ! Acoplamiento fuerte Para esta categoría se tiene software cuyos elementos se interrelacionan mucho unos con otros y posibilitan la mayoría de las funcionalidades del cluster de manera altamente cooperativa. El caso de acoplamiento más fuerte que se puede dar es que solamente haya una imagen del Kernel del sistema operativo, 7 1. DESCRIPCIÓN DE LOS CLUSTER distribuida entre un conjunto de nodos que la compartirán. Por supuesto algo fundamental es poder acceder a todas las partes de este sistema operativo, estrechamente relacionadas entre sí y distribuidas entre los nodos. Este caso es el que se considera como más acoplado, de hecho no está catalogado como cluster, sino como sistema operativo distribuido. Otro ejemplo son los cluster SSI (Single System Image), en estos cluster los nodos ven una misma imagen del sistema, pero los nodos tienen su propio sistema operativo, aunque estos sistemas están estrechamente relacionados para dar la sensación a las aplicaciones que los nodos son idénticos y se acceda de una manera homogénea a los recursos del sistema total. Si ejecuta una aplicación, ésta verá un sistema homogéneo, por lo tanto los Kernels tienen que conocer los recursos de otros nodos para presentarle al sistema local los recursos que encontraría si estuviera en otro nodo. Es necesario un sistema de nombres único, manejado de sistema distribuida o centralizada y un mapeo de los recursos físicos a este sistema de nombres. Figura 1.4. Figura 1.4. Acoplamiento fuerte ! Acoplamiento medio A este grupo pertenece un Software que no necesita un conocimiento tan exhaustivo de los recursos de otros nodos, pero que sigue usando el Software de otros nodos para aplicaciones de muy bajo nivel. Como es el caso de OpenMosix y Linux-HA. Un cluster OpenMosix necesita que los Kernels sean de la misma versión. Por otro lado no está tan acoplado como el caso anterior: no necesita un sistema de nombres común en los nodos, y su capacidad de dividir los procesos en una parte local y otra remota consigue que por un lado se necesite el Software del 8 1. DESCRIPCIÓN DE LOS CLUSTER otro nodo donde está la parte del archivo que falta en el nodo local y por otro que no se necesite un SSI para hacer otras tareas. Figura 1.5. Figura 1.5. Acoplamiento medio • Acoplamiento débil Generalmente se basan en aplicaciones construidas por bibliotecas preparadas para aplicaciones distribuidas. Es el caso de PVM, MPI o CORBA. Éstos por sí mismos no funcionan en modo alguno con las características que antes se han descrito (como Beowulf) y hay que dotarles de una estructura superior que utilice las capacidades del cluster para que éste funcione. Figura 1.6. (miKel & Buytaert, 2004). Figura 1.6. Acoplamiento débil 9 1. DESCRIPCIÓN DE LOS CLUSTER 1.4. Esquema y otras características Las características básicas de un cluster de carácter general se resumen en el siguiente esquema: 1. Un cluster consta de 2 o más nodos conectados entre sí por un canal de comunicación funcional. 2. En cada nodo es imprescindible un elemento de proceso, memoria y un interfaz para comunicarse con la red del cluster. 3. Los cluster necesitan software especializado. Este software y las computadoras conforman el cluster. El software puede ser: a. Aplicación b. Sistema 4. Se define acoplamiento de un cluster como nivel de colaboración que une los elementos del cluster. De este modo se clasifican en: a. Acoplamiento fuerte b. Acoplamiento medio o moderado c. Acoplamiento débil 5. Todos los elementos del cluster trabajan para cumplir una funcionalidad conjunta, sea esta la que sea. Es la funcionalidad la que caracteriza el sistema. Además de las presentadas anteriormente se agregan otra serie de características necesarias: ! Mejora sobre la disponibilidad ! Mejora del rendimiento En general la manera de catalogar a los cluster se hace en base a cuatro factores de diseño bastante ortogonales entre sí: ! ! ! ! Acoplamiento (definido anteriormente en el inciso 1.3) Control Homogeneidad Seguridad 1.4.1. El factor de control del cluster El parámetro de control implica el modelo de gestión que propone el cluster. Este modelo de gestión hace referencia a la manera de configurar el cluster y es dependiente del modelo de conexionado o colaboración que surgen entre los nodos. Puede ser de dos tipos: 10 1. DESCRIPCIÓN DE LOS CLUSTER ! Control centralizado: se hace uso de un nodo maestro desde el cual se puede configurar el comportamiento de todo el sistema. Este nodo es un punto crítico del sistema aunque es una ventaja para una mejor gestión del cluster. ! Control descentralizado: en un modelo distribuido donde cada nodo debe administrarse y gestionarse. También pueden ser gestionados mediante aplicaciones de más alto nivel de manera centralizada, pero la mayoría de la gestión que hace el nodo local es leer archivos de configuración de su propio nodo. 1.4.2. Seguridad Es propio de sistemas distribuidos, como ventaja tiene que presenta más tolerancia a fallas como sistema global y como desventajas que la gestión y administración de los equipos requiere más tiempo. 1.4.3. Homogeneidad En la homogeneidad de un cluster se ha demostrado que es posible crear sistemas de una sola imagen o heterogéneos con una implementación práctica. En cualquier caso, hay que entender por homogeneidad del cluster a la homogeneidad de los equipos y recursos que conforman a éste. Los cluster heterogéneos son más difíciles de conseguir ya que se necesitan notaciones abstractas de transferencias e interfaces especiales entre los nodos para que éstas se entiendan, por otro lado los cluster homogéneos obtienen más beneficios de estos sistemas y pueden ser implementados directamente a nivel de sistema (miKel & Buytaert, 2004). 1.4.3.1. Homogeneidad de un cluster ! Homogéneos: están formados por equipos de la misma arquitectura. Los nodos tienen una arquitectura y recursos similares, de manera que no existen muchas diferencias entre cada nodo. ! Heterogéneos: formados por nodos con distinciones que pueden estar en los siguientes puntos. o Tiempos de acceso distintos o Arquitectura distinta o Sistema operativo distinto o Rendimiento de los procesadores o recursos sobre una misma arquitectura distintos El uso de arquitecturas distintas o distintos sistemas operativos, impone que exista una biblioteca que haga de interfaz, e incluso una sintaxis de notación abstracta del tipo ASN.1 o XDR en la capa de presentación que utilice la interfaz de comunicación de 11 1. DESCRIPCIÓN DE LOS CLUSTER nuestro sistema distribuido o cluster. Esto hace que este tipo de cluster se consideren implementados a nivel de aplicación. Existen otros factores de diseño que limitan el comportamiento y modelado de un cluster. La imposibilidad de llegar a cluster que paralelicen cualquier proceso se basa en que la mayoría de las aplicaciones hacen uso, en mayor o menor medida, de algoritmos secuenciales no paralelizables (Hwang & Xu, 1998). 1.5. Clasificación de los cluster Los cluster son diseñados para dar solución a problemas donde apliquen una mejora en rendimiento, el costo de implementar un cluster comparándolo con el de adquirir un Mainframe es realmente accesible y el rendimiento que proporciona un cluster puede llegar a ser igualado. Por otro lado esta la distribución de riesgos. La mayoría de los usuarios tienen sus servicios, aplicaciones, bases de datos o recursos en una sola computadora o son dependientes de una sola computadora. Otro aspecto importante es colocar las bases de datos replicadas sobre sistemas de archivos distribuidos de manera que estos no se pierdan por que los datos son un recurso importante. Actualmente el mercado de la informática exige no solo que los datos sean críticos sino que los servicios estén activos constantemente. Esto exige medios y técnicas que permitan que el tiempo en el que una computadora esté inactiva sea el menor posible. La distribución de factores de riesgo a lo largo de un cluster (o la distribución de funcionalidades en casos más generales) permite de una forma única obtener la funcionalidad de una manera más confiable: si una computadora cae otras podrán dar el servicio. Por último está el factor de escalabilidad, cuanto más escalable es un sistema menos costará mejorar el rendimiento, lo cual abarata el costo y en el caso de que el cluster lo implemente distribuye más el riesgo de caída de un sistema (Coulouris & Dollimore, 2003). 1.5.1. Alto rendimiento (HP High Performance) Los cluster de alto rendimiento han sido creados para compartir el recurso más valioso de una computadora, es decir, el tiempo de proceso. Cualquier operación que necesite altos tiempos de CPU puede ser utilizada en un cluster de alto rendimiento, siempre que se encuentre un algoritmo que sea paralelizable (ejecución de distintas actividades desde procesadores diferentes). Existen cluster que pueden ser denominados de alto rendimiento tanto a nivel de sistema como a nivel de aplicación. A nivel de sistema tenemos OpenMosix, mientras que a nivel de aplicación se encuentran otros como MPI, PVM, Beowulf, entre otros. En cualquier caso, estos cluster hacen uso de la capacidad de procesamiento que pueden tener varias computadoras (Coulouris & Dollimore, 2003). 12 1. DESCRIPCIÓN DE LOS CLUSTER 1.5.1.1. Problemas que solucionan Generalmente estos problemas de cómputo están ligados a: • • • • • • Cálculos matemáticos Renderizaciones de gráficos (generación de gráficos vectoriales) Compilación de programas Compresión de datos Descifrado de códigos Rendimiento del sistema operativo (incluyendo, el rendimiento de los recursos de cada nodo) Existen otros problemas que se pueden solucionar con cluster HP, donde cada uno aplica de una manera u otra las técnicas necesarias para habilitar la paralelización del problema, su distribución entre los nodos y obtención del resultado (Fink & Sherer, 2003). 1.5.1.2. Técnicas que utilizan Las técnicas utilizadas dependen de a qué nivel trabaje el cluster. Los cluster implementados a nivel de aplicación no implementan balanceo de carga. Los cluster basar todo su funcionamiento en una política de localización que sitúa las tareas en los diferentes nodos del cluster y las comunica mediante las librerías abstractas. Resuelven problemas de cualquier tipo, pero se deben diseñar y codificar aplicaciones propias para cada tipo para poderlas utilizar en estos cluster. Por otro lado están los sistemas de alto rendimiento implementados a nivel de sistema. Estos cluster basan su funcionamiento en comunicación y colaboración de los nodos a nivel de sistema operativo, lo que implica generalmente que son cluster de nodos de la misma arquitectura, con ventajas en lo que se refiere al factor de acoplamiento y que basan su funcionamiento en compartir los recursos a cualquier nivel, balanceo de la carga de manera dinámica, funciones de planificación especiales y otros tantos factores que componen el sistema. Se acerca a sistemas SSI (Single System Image), el problema está en que para obtener un sistema SSI hay que ceder en el apartado de compatibilidad con los sistemas actuales, por lo cual se llega a un factor de compromiso. Entre las limitaciones que existen actualmente está la incapacidad de balancear la carga dinámica de las librerías PVM o la incapacidad de OpenMosix de migrar procesos que hacen uso de memoria compartida. Una técnica que obtiene mayor ventaja es cruzar ambos sistemas: PVM + OpenMosix. Se obtiene un sistema con un factor de acoplamiento elevado que presta las ventajas de uno y otro, con una pequeña limitación por desventajas de cada uno (Fink & Sherer, 2003). 13 1. DESCRIPCIÓN DE LOS CLUSTER 1.5.2. Alta disponibilidad (HA High Availability) Los cluster de alta disponibilidad son bastante ortogonales en lo que se refieren a funcionalidad a un cluster de alto rendimiento. Pretenden dar servicios de cualquier tipo los 365 días del año, son cluster donde la principal funcionalidad es estar controlando y actuando para que un servicio u otros se encuentren activos durante el máximo periodo de tiempo posible. En estos casos se puede comprobar como la monitorización de otros es parte de la colaboración entre los nodos del cluster. Son los más solicitados por las empresas ya que están destinados a mejorar los servicios que éstas ofrecen cara a los clientes en las redes a las que pertenecen, tanto en redes locales como en redes como Internet. Los cluster de alta disponibilidad han sido diseñados para la máxima disponibilidad sobre los servicios que presenta el cluster. Este tipo de cluster es la competencia que abarata los sistemas redundantes, de manera que ofrecen una serie de servicios durante el mayor tiempo posible. Para poder dar estos servicios los cluster de este tipo se implementan en base a tres factores: ! Fiabilidad ! Disponibilidad ! Dotación de servicio Mediante estos tres tipos de actuaciones y los mecanismos que lo implementan se asegura que un servicio esté el máximo tiempo disponible y que éste funcione de una manera fiable. Respecto al tercer punto, se refiere a la dotación de uno de estos cluster de un servicio que provea a clientes externos (miKel & Buytaert, 2004). 1.5.2.1. Problemas que solucionan La mayoría de estos problemas están ligados a la necesidad de dar servicio continuo de cualquier tipo a una serie de clientes de manera ininterrumpida. En una construcción real se producen fallas inesperadas en las computadoras, estas fallas provocan la aparición de dos eventos en el tiempo: el tiempo en el que el servicio está inactivo y el tiempo de reparación del problema. Entre los problemas que solucionan se encuentran: ! ! ! ! Sistemas de información redundante Sistemas tolerantes a fallas Balanceo de carga entre distintos servidores Balanceo de conexiones entre distintos servidores En general estos problemas se ligan en dos fuentes de necesidad de las empresas u organizaciones: 14 1. DESCRIPCIÓN DE LOS CLUSTER ! Tener un servicio disponible ! Ahorrar económicamente todo lo que sea posible El servicio puede ser diverso. Desde un sistema de archivos distribuidos de carácter muy barato, hasta grandes cluster de balanceo de carga y conexiones para los grandes portales de Internet. Cualquier funcionalidad requerida en un entorno de red puede ser colocada en un cluster e implementar mecanismos para hacer que esta obtenga la mayor disponibilidad posible (miKel & Buytaert, 2004). 1.5.2.2. Técnicas que utilizan Como se ha estado mencionando los servicios y el funcionamiento de los mismos son de carácter distinto, en cualquier caso, se proponen sistemas desde SSI que plantean serias dudas en lo que se refiere a localización de un servidor, hasta balanceo de carga o de conexiones. También contienen secciones de código que realizan monitorización de carga o monitorización de servicios para activar las acciones necesarias para cuando estos caigan. Se basan en principios que pueden ser desarrollados hasta crear sistemas complejos especializados para cada entorno particular. En cualquier caso, las técnicas de estos sistemas se basan en excluir del sistema aquellos puntos críticos que pueden producir una falla y por lo tanto la pérdida de disponibilidad de un servicio. Para esto se implementan desde enlaces de red redundantes hasta disponer de N computadoras para hacer una misma tarea de manera que si caen N-1 computadoras el servicio permanece activo sin pérdida de rendimiento. 1.5.3. Alta confiabilidad (HR High Reliability) Por último, están los cluster de alta confiabilidad. Estos cluster tratan de aportar la máxima confiabilidad en un entorno, en la cual se necesite saber que el sistema se va a comportar de una manera determinada. Puede tratarse por ejemplo de sistemas de respuesta en tiempo real. Este tipo de cluster son los más difíciles de implementar. No se basan solamente en conceder servicios de alta disponibilidad, sino en ofrecer un entorno de sistema altamente confiable. Esto implica demasiada sobrecarga en el sistema, son también cluster muy acoplados. Dar a un cluster SSI capacidad de alta confiabilidad implica gastar recursos necesarios para evitar que aplicaciones interrumpan su funcionalidad. En los cluster de alta disponibilidad generalmente una vez que el servicio ha caído éste se relanza, y no existe manera de conservar el estado del servidor anterior, más que mediante puntos de parada o checkpoints, pero que en conexiones en tiempo real no son suficientes. Por otro lado, los cluster confiables tratan de mantener el estado de las 15 1. DESCRIPCIÓN DE LOS CLUSTER aplicaciones, no simplemente de utilizar el último checkpoint del sistema y relanzar el servicio. Generalmente este tipo de cluster se utiliza para entornos de tipo empresarial y esta funcionalidad solamente puede ser efectuada por Hardware especializado. Por el momento no existe ninguno de estos cluster implementados como Software. Esto se debe a limitaciones de la latencia de la red, así como a la complejidad de mantener los estados. Se hacen necesarias características de cluster SSI, tener un único reloj de sistema conjunto y otras más. Dada la naturaleza asíncrona actual en el campo de los cluster, este tipo de cluster aún será difícil de implementar hasta que no se abaraten las técnicas de comunicación (miKel & Buytaert, 2004). 1.6. Tecnologías similares a cluster tipo Beowulf Adicionalmente a los Cluster tipo Beowulf, existen las siguientes tecnologías similares: MOSIX. Esta tecnología basada en Linux, permite realizar balance de carga para procesos particulares en un cluster. Trabaja como un Cluster de Alto Rendimiento en el sentido de que está diseñado para tomar ventaja del hardware más rápido disponible en el cluster para cualquier tarea que le sea asignada; pero, lo realiza balanceando la carga de las distintas tareas en varias computadoras. Una de las grandes ventajas de MOSIX es que no requiere la elaboración de Software especial como lo requiere los cluster tipo Beowulf. Los usuarios ejecutan sus programas normalmente y el sistema MOSIX se encarga del resto. Otra tecnología de cluster es el paquete Piranha, que permite a los servidores Linux proveer alta disponibilidad sin la necesidad de invertir cantidades mayores en Hardware. La tecnología de cluster es basado completamente en Software, donde los servidores se comunican en una red de alta velocidad. Se puede configurar para trabajar como Cluster de Alta Disponibilidad o de Balance de Carga. El Piranha puede configurar un servidor de respaldo en caso de falla de la contraparte. También puede hacer que el cluster aparezca como un servidor virtual (Beowulf,2003). 1.7. Estado del arte A continuación se listan los centros de trabajo donde se encuentran implementados cluster tipo Beowulf de alto rendimiento en el país: 1. Implementación de Sistemas de Cómputo de Alto Rendimiento de Aplicaciones Científicas en la Universidad de Sonora Tiene como objetivos: 16 1. DESCRIPCIÓN DE LOS CLUSTER ! Formar personal en construcción de Clusters de PCs con el sistema operativo Linux, para apoyar las actividades de Supercómputo en la Universidad de Sonora ! Apoyar la investigación interdisciplinaria en Ciencias de la Computación, Física y Matemáticas Computacionales, y Geocomputación ! Desarrollar sistemas de cómputo distribuido de apoyo académico al Área de Redes y Sistemas Distribuidos de la Licenciatura en Ciencias de la Computación de la Universidad de Sonora (Lizarraga, 2002). Metas ! Construir Clusters Clase Beowulf de aplicaciones científicas en la Universidad de Sonora ! Integrar bibliotecas de software de fuente abierta de aplicaciones científicas ! Formar estudiantes de Ciencias de la Computación del área de Sistemas Distribuidos en Clusters Cuenta con un grupo de apoyo en Supercómputo en las Áreas de Ciencias e Ingeniería (Lizarraga, 2002). Se colaborará en el ACARUS de la Dirección de Investigación y Postgrado de la Universidad de Sonora en los siguientes proyectos: ! Instalación y configuración de las bibliotecas MPI en el sistema Digital UNIX de multiprocesadores, para aplicaciones de cómputo paralelo ! Construcción de la biblioteca de software libre de fuente abierta de aplicaciones de supercómputo ! Construcción y configuración del Cluster ACARUS tipo Beowulf de 16 nodos ! Dar apoyo en soporte de cómputo académico, para la migración de programas al Cluster Beowulf (Lizarraga,2002). 2. Universidad Autónoma de Baja California Instituto de Investigaciones Oceanológicas. Cluster UABC Objetivos: El CICESE y la UABC se unan a la iniciativa hecha por la Cámara Nacional de la Industria Electrónica, de Telecomunicaciones e Informática (CANIETI) y el Colegio de Profesionales de Tecnologías de Información en Baja California (CPTI) para desarrollar un cluster de software en el estado (Velásquez, 2004). La vinculación con organismos empresariales nacionales e internacionales y la participación en las decisiones de la industria son objetivos de la cámara de Tecnologías de Información de la CANIETI. El Hardware que utiliza es de un cluster de 26 procesadores (duales): ! 16 de ellos Pentium III a 550MHz con 256MB RAM y Fast Ethernet ! 10 de ellos Pentium III a 600MHZ con 512MB RAM y Fast Ethernet Facultad de Ciencias 17 1. DESCRIPCIÓN DE LOS CLUSTER ! Cluster de 5 Dual-Penitum II a 550MHz con 256 MB RAM y Fast Ethernet Facultad de Ingeniería ! Cluster de 5 Dual-Penitum II a 550MHz con 256 MB RAM y Fast Ethernet Conectados con switches de 16 puertos y 24 puertos. 3. Instituto de Física, UNAM Este proyecto es responsable de la implementación, desarrollo y operación de un cluster de computadoras paralelas de clase Beowulf dividido en dos subclusters, uno de ellos integrado por 16 nodos con 32 procesadores Pentium III y el otro por 4 nodos con 8 procesadores Alpha. Ambos proporcionan una capacidad total de supercómputo de gigaflops (Moreno, 2000). El cluster es utilizado por investigadores y estudiantes del IFUNAM para el estudio de temas de frontera en física y temas afines (Moreno, 2000). Software El software de cada una de los clusters fue preinstalado por el distribuidor, el cual básicamente es el sistema operativo GNU/Linux Red Hat con algunas modificaciones al kernel para un mejor desempeño y bibliotecas MPICH, MPI LAM y PVM para programación en paralelo. Tiene instalado software principalmente para la administración del cluster y el compilador de Fortran de absoft, absoft es conocido por sus series de compiladores de alto desempeño en clusters de computadoras (Moreno, 2000). 4. El Instituto de Astronomía de la UNAM Tiene implementado un cluster de nombre Emong, es un cluster tipo Beowulf, el uso es principalmente para la simulación hidrodinámica por el Grupo Teórico de Estrellas de Neutrones, el Hardware que se implemento esta conformado por 20 CPUs Pentium III con una velocidad de 450 Mhz (Lizarraga, 2002). 5. El departamento de Matemáticas y Mecánica del IIMAS de la UNAM Tiene implementado un cluster tipo Beowulf, este cluster es utilizado para ejecutar aplicaciones de alto rendimiento utilizando, el Hardware que se implemento esta formado por 5 nodos con 2 procesadores Pentium III a 750 Mhz cada uno y con 256 MB de RAM, el sistema operativo que se utiliza es Linux RedHat 7.1 con kernel 2.4.2. (supercomputo, 2003). En un apartado denominado ANEXO 1, se incluyen los conceptos básicos de los Cluster, clasificados por tipos de cluster, definiciones básicas, cómputo paralelo y componentes de los cluster. 18 2. CLUSTER DE APLICACIÓN. 2. CLUSTER DE APLICACIÓN. 2.1. Conceptos de Migración y Balanceo Los clusters de Alto Rendimiento (HP) están dedicados a dar el mayor rendimiento computacional posible y existen diversas formas de implementarlos. Las implementaciones se dividen en soluciones que funcionan a nivel de aplicación y a nivel de Kernel. Las implementaciones que funcionan a nivel de aplicación se presentan en forma de librería. Se realizan programas donde se reutiliza el código ya existente y para mejorar su rendimiento se reescribe alguna parte. Este tipo de implementaciones presentan diversos inconvenientes, entre los cuales se mencionan: • La variedad de las aplicaciones que necesitan grandes tiempos de cómputo se realizaron hace décadas en lenguaje Fortran • Los programas existentes enfocados a aplicaciones matemáticas ó físicas, son difíciles de comprender • La migración es difícil en el nuevo entorno distribuido Por otro lado una ventaja de implementarse es: • Son económicos respecto a las supercomputadoras En las implementaciones que funcionan a nivel de Kernel, es el Software el que se encarga del HP; para este caso no se necesitan cambiar las aplicaciones del usuario, ya que internamente el Kernel es le que se encarga de distribuir el trabajo de forma que resulte transparente para la aplicación (Barroso & at all, 2003). Las desventajas que se tienen son: • El Kernel se vuelve complejo y esta expuesto a fallas • Las soluciones son específicas de un Kernel, esto indica que si las aplicaciones no están diseñadas para el sistema operativo para el que fue elaborado tendrá fallas La ventaja radica en que no hay necesidad de una inversión económica para cambiar aplicaciones, ya que cualquier aplicación puede ser distribuida, un factor que hay que considerar de manera permanente es la programación de la aplicación. 19 2. CLUSTER DE APLICACIÓN. Existen dos formas que permiten conseguir que los HP migren procesos, dividir las aplicaciones grandes en procesos y ejecutar cada proceso en un nodo distinto, logrando el máximo uso de los recursos en todo momento, especialmente con los procesadores: 1. Asignar estáticamente cada proceso a un nodo en particular Para esta forma es importante saber la localización. Se elige estáticamente el nodo donde el proceso estará en uso, esto implica saber elegir el o los nodos; la mayoría de las veces esto implicara que se requiera de un administrador, el cual decidirá donde debe ir cada proceso. Un caso considerado como simple es tener los nodos con la misma potencia de cálculo y dividir el único programa al que se quiera dedicar los recursos en un número de procesos que debe ser igual al número de nodos con los que se disponen. De esa forma se asignaría cada proceso a uno de los nodos. Es importante que se tome en cuenta que esta configuración resulta lejana a lo normal y que una falla en el algoritmo de elección de nodo puede inutilizar diversos recursos, la configuración manual es algo habitual en estos algoritmos. Cuando se utiliza este tipo de proceso, teniendo la configuración inicial se pretende que los procesos estén ejecutándose durante años si así se requiere. 2. Asignar dinámicamente procesos a los nodos Los procesos una vez iniciados en un nodo pueden migrar a otro nodo dinámicamente. En estos también es importante la política de localización para minimizar el gasto de recursos, así como la política de migración. Esto facilita ubicar los procesos manualmente, con la ventaja de que se puede ubicar en cualquier momento durante el tiempo de ejecución del proceso. Si la política de migración es correcta y los procesos tienen una vida larga y se ha dividido correctamente la aplicación, debería haber al comienzo de la ejecución de los procesos un periodo de reordenación de los procesos, con varias migraciones, una vez el sistema llegara a una condición estable, no deberían producirse apenas migraciones hasta que los procesos finalizaran. Igual que ocurre en el caso anterior, esta configuración es lejana a la habitual, pero al contrario del caso anterior, aquí no es necesaria la configuración manual (si el algoritmo de migración es suficientemente bueno). Cuando se desbalancea el sistema éste se encarga de que se vuelva a balancear, de tal forma de que se aprovechen los recursos al máximo. Por tanto estos algoritmos intentan tener un fundamento matemático fuerte que intenta minimizar el tiempo de cómputo. Estos sistemas usan fundamentos estadísticos, como por ejemplo openMosix. OpenMosix intenta maximizar el uso de los recursos. Intentar solamente balancear respecto al procesador puede dar lugar a decisiones erróneas, porque se pueden enviar procesos que no hagan mucho uso del procesador a uno de los nodos, si estos 20 2. CLUSTER DE APLICACIÓN. procesos están haciendo entrada/salida y son procesos grandes, es muy posible que el nodo empiece a hacer trashing e implicara quedarse sin memoria, con lo que los procesos no podrán ejecutar su función (Byna& ALL, 2003). En la tabla 2.1 se muestran las posibles formas que existen para clusters. Con ello se listan las diversas posibilidades de decidir que es lo que se hace cuando se implementa un cluster de este tipo. Tabla 2.1. Clusters HP. Aspectos de implementación Tema Sin requisa de procesos Con requisa de procesos Balanceo estático Balanceo dinámico Nivel de aplicación Nivel de Kernel Nodos dedicados Nodos comparten espacio Nodos comparten tiempo Scheduling independiente Scheduling de grupo Con carga externa, quedarse Ante carga externa, migrar Problemas que genera Mayor latencia para procesos de alta prioridad Sobrecarga, implementación compleja Mal balanceo de carga Sobrecarga, implementación compleja Sobrecarga, falta de información Dificultad de implementación Infrautilización de recursos Se necesita una política eficiente de localización Sobrecarga cambio de contexto Pérdida de rendimiento Implementación compleja Pérdida de rendimiento en trabajos locales Sobrecarga de migración, límites de migración Requisa se refiere a poder parar el proceso y tomar sus recursos (básicamente los registros del procesador y memoria). La requisa de los procesos puede existir o no. Cuando un sistema es multitarea normalmente se implementa algún sistema de requisa para poder parar procesos y hacer que otros procesos tomen el procesador para dar la sensación al usuario de que los procesos se están ejecutando concurrentemente. Si no se implementa requisa, un proceso de baja prioridad puede tomar el procesador y otro proceso de alta prioridad no podrá tomarlo hasta que el proceso de baja prioridad lo ceda a otros procesos. Este esquema puede ser injusto con las prioridades y un error en un programa, puede llegar a dejar sin funcionar la computadora pues nunca devolvería el control, pero tampoco haría ningún trabajo útil. Además para sistemas que necesitan tiempo real, simplemente es inaceptable que procesos de baja prioridad estén dejando a los procesos de tiempo real sin tiempo de procesador y quizás con esta latencia extra se esté haciendo que el sistema no pueda cumplir sus operaciones en tiempo real, haciendo que el sistema sea inútil. Hoy en día la requisa se implementa al menos a un nivel elemental en los sistemas que necesiten hacer funcionar más de un proceso. 21 2. CLUSTER DE APLICACIÓN. Algunos sistemas lo que hacen es no esperar a que cumpla un temporizador y realizar la requisa sino a esperar que el proceso haga alguna llamada al sistema para aprovechar, tomar el procesador y cederlo a otro proceso. Esta aproximación sigue teniendo el problema de que si un proceso maligno o mal programado no hace llamadas a sistema porque haya quedado en un bucle, nunca se ejecutará nada en ese ambiente. Si se implementa la requisa hay que tener en cuenta que la implementación más simple que se puede dar necesita un temporizador que marque cuando se acabó el tiempo del proceso y requisar ese proceso para asignar a otro proceso. Esto impone una sobre carga pues hay que tratar una interrupción, actualizar unas variables para saber cuanto tiempo lleva un proceso trabajando. Hay una implementación más compleja que trata de que siempre que haya un proceso de una prioridad mayor al que se está ejecutando se quite el procesador al proceso y se dé el procesador al proceso con mayor prioridad. Estos son sistemas en tiempo real que también pueden tener otras exigencias como tiempos mínimos de latencia para ciertos procesos. Para conseguir esto, el Kernel no solamente tiene que requisar procesos de baja prioridad en favor de los procesos de tiempo real sino que tiene que ser capaz de requisar su propio código. Esto puede significar cualquier porción del código del Kernel se pueda ejecutar entre dos instrucciones de este mismo código. Esto presenta problemas a la hora de programar, se tiene que evitar condiciones de carrera dentro del propio Kernel que antes por ser código no requisable no se podían dar. Por tanto implementar requisa, puede hacer que un sistema sea tiempo real pero complica tremendamente el núcleo del sistema. (miKel & Buytaert, 2004) Las siguientes tres líneas de la tabla 2.1 tratan sobre los recursos del cluster, estos son los nodos. Existen tres modos en los que se puede dedicar los nodos del cluster, estos modos son: a) Modo dedicado Con este modo solamente es asignado a un nodo en cualquier momento un trabajo está siendo ejecutado en el cluster y solo un proceso se está ejecutando, este trabajo no liberará el cluster hasta que acabe completamente aun cuando solo quede un proceso por ejecutarse. Los recursos se dedican a este trabajo, esta forma de uso de un cluster lleva a una pérdida importante de potencia sobre todo si no todos los nodos acaban el trabajo al mismo tiempo. b) Modo de división en el espacio Con este modo, n-trabajos se pueden ejecutar en distintas particiones del cluster los cuales son considerados como grupos de nodos. Un proceso puede estar asignado a un cluster, las particiones se dedican a un trabajo, la interconexión y el sistema de entrada/salida pueden estar compartidos por los trabajos, logrando aprovechar los recursos. Los grupos de los nodos son estáticos y los programas para ejecutarse necesitan un número específico de nodos, teniendo con ello por consideraciones: 22 2. CLUSTER DE APLICACIÓN. • Puede haber trabajos donde no haya una división lo suficientemente grande por lo cual no puedan ser ejecutados • Puede haber trabajos donde se aprovechen nodos y desperdiciando una división considerable de nodos. Para evitar esto se tienen que usar técnicas para ser elegidos los nodos donde se ejecutaran los trabajos, esto para minimizar el número de nodos ociosos • También puede ocurrir que un trabajo muy largo tome los recursos del cluster evitando que otros trabajos más rápidos acaben, esto consigue aumentar la latencia c) Modo de división en el tiempo En cada nodo pueden estar ejecutándose diversos procesos a la vez por lo que se solucionan los problemas anteriores. Este es el modo más usado normalmente ya que no tiene tantas restricciones como el modo de división en el espacio y si se eligen correctamente los procesos se pueden equilibrar (miKel & Buytaert, 2004). Los dos siguientes puntos de la tabla 2.1. tratan sobre scheduling, esta planificación solo se da cuando el modo que se ha elegido es el modo de división en el tiempo. Hay dos tipos de scheduling en cuanto a clusters se refiere: 1. Scheduling independiente Es el caso más sencillo y más implementado, se usa un sistema operativo en cada nodo del cluster para hacer scheduling de los distintos procesos en un nodo tradicional, esto también es llamado scheduling local. Sin embargo, el rendimiento de los trabajos paralelos que esté llevando a cabo el cluster puede verse degradado en gran medida. Cuando uno de los procesos del trabajo paralelo quiera hacer cualquier tipo de interacción con otro proceso como sincronizarse con él, puede suceder que este proceso no esté ejecutándose en esos momentos y que aún se tarde un tiempo hasta que se ejecute por otro tanto de tiempo. Esto quiere decir que el primer proceso tendrá que esperar y cuando el segundo proceso esté listo para interactuar quizás el primer proceso esté en swap y tenga que esperar a ser elegido otra vez para funcionar. (miKel & Buytaert, 2004) 2. Scheduling de grupo Cuando uno de los procesos está activo, todos los procesos están activos. Este tipo de scheduling puede aumentar el rendimiento en uno o dos puntos de magnitud. Los nodos del cluster no están perfectamente sincronizados. De hecho, la mayoría de los clusters son sistemas asíncronos (que no usan el mismo reloj). 23 2. CLUSTER DE APLICACIÓN. Para lograr los resultados de rendimiento se debe dejar que los procesos se ejecuten de forma continua por un tiempo considerable ó en su defecto la diferencia que exista entre la ejecución de un proceso y el último sea relativamente corto (miKel & Buytaert, 2004). Por tanto hacer scheduling en un cluster grande, siendo el scheduling una operación compleja y que tiene que estar optimizada al máximo es una operación bastante difícil de lograr, se necesitaría la información de los nodos para tomar buenas decisiones, esto implicaría contar con redes rápidas. Las dos últimas filas de la tabla 2.1. se refieren a que se trata de que deben hacer los procesos cuando se encuentran que en su nodo local ya que hay otros procesos que provienen de otros nodos. Estos pueden venir por alguna política de migración o porque se esté ejecutando el scheduler de grupo. Los trabajos locales podrían tener prioridad sobre trabajos externos, por decir los procesos de usuario interactivos donde no se quiere que se degrade el rendimiento deben mantener mayor prioridad. Hay dos formas de tratar esta situación: a) El trabajo externo migra: si el proceso migra, el proceso puede ir a un nodo donde se ejecute de forma más eficiente. b) El trabajo externo se mantiene en el cluster: si el proceso se mantiene en el nodo donde se encuentra se evita la sobrecarga que conlleva la migración, para no afectar a los procesos de ese nodo se les da muy poca prioridad (miKel & Buytaert, 2004). 2.1.2. PVM (Parallel Virtual Machine) y MPI (Message Passing Interface) Hay diferentes formas de hacer procesamiento paralelo, entre las más conocidas y usadas se encuentran: NUMA, PVM y MPI. Las computadoras de tipo NUMA (Non-Uniform Memory Access) tienen acceso compartido a la memoria donde pueden ejecutar su código de programa. En el Kernel de Linux hay ya implementado NUMA, que hace variar el número de accesos a las diferentes regiones de memoria. PVM/MPI son herramientas que han estado ampliamente utilizadas y son muy conocidas por la gente que entiende de supercomputación basada en GNU/Linux. MPI es el estándar abierto de bibliotecas de paso de mensajes. MPICH es una de las implementaciones más usadas de MPI, tras MPICH se puede encontrar LAM, otra implementación basada en MPI también con bibliotecas de código abierto. PVM es una variante de MPI que también es ampliamente usado para funcionar en entornos Beowulf. 24 2. CLUSTER DE APLICACIÓN. PVM habita en el espacio de usuario y tiene la ventaja que no hacen falta modificaciones en el Kernel de Linux, básicamente cada usuario con derechos suficientes puede ejecutar PVM (Carns& all, 2000). 2.1.3. Paso de mensajes PVM como MPI se basan en el concepto de paso de mensajes. Los mensajes son pasados entre los procesos para conseguir que se ejecuten de manera colaborativa y de forma sincronizada. Los mensajes se pueden implementar de una forma efectiva en un cluster, los mensajes se envían en forma de paquete IP y la computadora destino desempaqueta el mensaje decidiendo a que proceso va dirigido. Una vez hecho esto, envía la información al proceso en cuestión. MPI en particular se necesita conocer de forma básica los mecanismos de paso de mensajes. Hay tres mecanismos básicos de paso de mensajes: 1. Paso de mensajes síncrono Cuando un proceso P ejecuta un envío síncrono a un proceso Q, tiene que esperar hasta que el proceso Q ejecuta el correspondiente recibo de información síncrono. Ambos procesos no volverán del envío o el recibo hasta que el mensaje está a la vez enviado y recibido. Cuando el enviar y recibir acaban, el mensaje original puede ser inmediatamente sobrescrito por el nuevo mensaje de vuelta y éste puede ser inmediatamente leído por el proceso que envió originariamente el mensaje. No se necesita un buffer extra en el mismo buffer donde se encuentra el mensaje de ida, se escribe el mensaje de vuelta. 2. Enviar/Recibir bloqueante Un envío bloqueante es ejecutado cuando un proceso lo alcanza sin esperar el recibo correspondiente. Esta llamada bloquea hasta que el mensaje es efectivamente enviado, lo que significa que el mensaje puede ser reescrito sin problemas. Cuando la operación de enviar ha acabado no es necesario que se haya ejecutado una operación de recibir. Sólo sabemos que el mensaje fue enviado, puede haber sido recibido o puede estar en un buffer del nodo que lo envía o en un buffer de algún lugar de la red de comunicaciones o puede que esté en el buffer del nodo receptor. Un recibo bloqueante es ejecutado cuando un proceso lo alcanza, sin esperar a su correspondiente envío. Sin embargo no puede acabar sin recibir un mensaje. Quizás el sistema esté proveyendo un buffer temporal para los mensajes. 3. Envío/recibo no bloqueante Un envío no bloqueante es ejecutado cuando un proceso lo alcanza, sin esperar al recibo. Puede acabar inmediatamente tras notificar al sistema que debe enviar el mensaje. Los datos del mensaje no están necesariamente fuera del buffer del mensaje, por lo que es posible incurrir en error si se sobrescriben los datos. Un recibo no bloqueante es ejecutado cuando un proceso lo alcanza, sin esperar el envío. Puede volver inmediatamente tras notificar al sistema que hay un 25 2. CLUSTER DE APLICACIÓN. mensaje que se debe recibir. El mensaje puede que no haya llegado aún, puede estar todavía en transito o puede no haber sido enviado aún (Carns& all,2000). 2.2. PVM PVM es un conjunto de herramientas y librerías que emulan un entorno de propósito general compuesto de nodos interconectados de distintas arquitecturas. El objetivo es conseguir que ese conjunto de nodos pueda ser usado de forma colaborativa para el procesamiento paralelo. El modelo en el que se basa PVM es dividir las aplicaciones en distintas tareas (igual que ocurre con openMosix). Son los procesos los que se dividen por las computadoras para aprovechar los recursos. Cada tarea es responsable de una parte de la carga que conlleva esa aplicacion. PVM soporta tanto paralelismo en datos, como funcional o una mezcla de ambos. PVM permite que las tareas se comuniquen y sincronicen con las demás tareas de la computadora virtual, enviando y recibiendo mensajes, muchas tareas de una aplicación puedan cooperar para resolver un problema en paralelo. Cada tarea puede enviar un mensaje a cualquiera de las otras tareas, sin límite de tamaño ni de número de mensajes. El sistema PVM se compone de dos partes: La primera es un demonio, llamado pvmd que residen en los nodos que forman parte de la computadora virtual. Cuando un usuario quiere ejecutar una aplicación PVM, primero crea una computadora virtual para arrancar PVM. Entonces se puede ejecutar la aplicación PVM en cualquiera de los nodos. Los usuarios pueden configurar varias computadoras virtuales aunque se mezclen unas con las otras y se pueden ejecutar varias aplicaciones PVM simultáneamente. Cada demonio es responsable de todas las aplicaciones que se ejecutan en su nodo. Así el control está totalmente distribuido excepto por un demonio maestro, que es el primero que se ejecuto a mano por el usuario, los demás nodos fueron iniciados por el maestro y son esclavos. En todo momento siempre hay un pvmd maestro. Por tanto la computadora virtual mínima es de un miembro, el maestro. La segunda parte del sistema es la librería de PVM. Contiene un repertorio de primitivas que son necesarias para la cooperación entre los procesos o threads de una aplicación. Esta librería contiene rutinas para inicialización y terminación de tareas, envío y recepción de mensajes, coordinar y sincronizar tareas, broadcast, modificar la computadora virtual. Cuando un usuario define un conjunto de nodos, PVM abstrae toda la complejidad que tenga el sistema y toda esa complejidad se ve como una gran computadora de memoria distribuida llamada computadora virtual. Esta computadora virtual es creada por el 26 2. CLUSTER DE APLICACIÓN. usuario cuando se comienza la operación. Es un conjunto de nodos elegidos por el usuario. En cualquier momento durante la operación puede elegir nuevos nodos para la computadora virtual. Esto puede ser de gran ayuda para mejorar la tolerancia a fallas ya que se tienen nodos de reserva (PVM no tiene migración) por si alguno de los nodos fallara. Para conseguir abstraer toda la complejidad de las diferentes configuraciones, soporta la heterogeneidad de un sistema a tres niveles: • Aplicaciones: las subtareas pueden estar hechas para aprovechar las arquitecturas sobre la que funcionan. Por tanto como se puede elegir en que conjunto de nodos se ejecutarán unas tareas específicas, se pueden hacer aplicaciones con la arquitectura al máximo por lo que se puede optimizar y hacer que funcionen aplicaciones hechas para arquitecturas específicas con PVM. • Computadoras: nodos con distintos formatos de datos están soportados, incluyendo arquitecturas secuenciales, vectoriales, SMP. Abstrae little endian y big endian. • Redes: la computadora virtual puede ser interconectada gracias a distintas tecnologías de red. Para PVM, bajo él existe una red punto a punto, no fiable y no secuencial. Esto abstrae cualquier tecnología de red. Utiliza UDP e implementa toda la confiabilidad y todas las demás operaciones como broadcast en la propia librería PVM. PVM tiene un conjunto de interfaces que está basado en la observación de las necesidades de la mayoría de las aplicaciones, que están escritas en C y Fortran. Los enlaces para C y C++ para la librería PVM están implementados como funciones, siguiendo las reglas usadas por la mayoría de los sistemas que usan C, incluyendo los sistemas operativos tipo UNIX. Los enlaces para Fortran están implementados como subrutinas más que funciones. Todas las tareas están identificadas con un único identificador de tarea TID (Task IDentifier). Los mensajes son enviados y recibidos por TIDs. Son únicos en toda la computadora virtual y están determinados por el pvmd local y no se pueden elegir por el usuario. Varias funciones devuelven estos TIDs (pvm_mytid(), pvm_parent(), etc.) para permitir que las aplicaciones de los usuarios conozcan datos de las otras tareas. Existen grupos nombrados por los usuarios, que son agrupaciones lógicas de tareas. Cuando una tarea se une al grupo, a ésta se le asigna un único número dentro de ese grupo. Estos números empiezan en 0 y hasta el número de tareas que disponga el grupo. Cualquier tarea puede unirse o dejar cualquier grupo en cualquier momento sin tener que informar a ninguna otra tarea del grupo. Los grupos se pueden superponer y las tareas pueden enviar mensajes multicast a grupos de los que no son miembro. Cuando una tarea se quiere comunicar con otra ocurren una serie de cosas, los datos que la tarea ha enviado con una operación send, son transferidos a su demonio local quien decodifica el nodo de destino y transfiere los datos al demonio destino. Este demonio decodifica la tarea destino y le entrega los datos. Este protocolo necesita 3 transferencias de datos de las cuales solamente una es sobre la red. También se puede elegir una política de encaminado directo (dependiente de los recursos disponibles). En esta política tras la primera comunicación entre dos tareas los datos sobre el camino a 27 2. CLUSTER DE APLICACIÓN. seguir por los datos son guardados en una caché local. Las siguientes llamadas son hechas directamente gracias a esta información. De esta manera las transferencias se reducen a una transferencia sobre la red. Para comunicar entre sí los demonios pvmd se usa UDP que es más sencillo, sólo consume un descriptor de archivo y con un simple socket UDP se puede comunicar a los demás demonios. Además resulta sencillo colocar temporizadores sobre UDP para detectar fallas de nodo, pvmd o red. La comunicación entre las tareas y los pvmd es mediante TCP puesto que se necesita tener la seguridad de que los datos llegarán. En el caso de que sólo se haga una transferencia ésta es TCP por lo que hay que establecer la conexión primero por lo que resulta no ser benéfico. En la figura 2.1. se observan los distintos métodos de comunicación de PVM. Cada nodo tiene una estructura llamada host table. Esta tabla tiene una entrada (host descriptor) por cada nodo de la computadora virtual. El descriptor del nodo mantiene la información de la configuración del host, las colas de paquetes y los buffer de mensajes. Inicialmente la tabla sólo tiene la entrada del nodo maestro. Cuando un nuevo esclavo es incluido a la computadora virtual, la tabla del nodo maestro es actualizada para añadir al nuevo esclavo. Entonces esta nueva información es enviada por broadcast a los nodos que pertenezcan a la computadora virtual. De esta manera se actualizan todas las tablas y se mantienen consistentes. Figura: 2.1. Clusters HP. Comunicaciones en PVM Las aplicaciones pueden ver el Hardware como una colección de elementos de proceso virtuales sin atributos o pueden intentar explotar las capacidades de computadoras específicas, intentando posicionar ciertas tareas en los nodos más apropiados para ejecutarlas. PVM no tiene requisa de procesos dinámico, esto quiere decir que una vez que un proceso empieza en una determinada computadora seguirá en ella hasta que se muera. Esto tiene graves inconvenientes ya que se debe tener en cuenta que las cargas varían y a no ser que los procesos que se estén ejecutando sean muy homogéneos entre sí, el cluster se descompensa. Por lo tanto se tendrán unos nodos más cargados que otros y 28 2. CLUSTER DE APLICACIÓN. con seguridad algunos nodos terminaran su ejecución antes, esto daría como resultado tener nodos cargados y libres. Dando como resultado una perdida de rendimiento general. Otro problema de PVM es que está implementado a nivel de usuario, esto resulta contraproducente ya que se encontraran operaciones de bajo nivel como lo es el paso de mensajes entre las aplicaciones y la capa sobre UDP. Esto añadirá complejidad y latencia a las comunicaciones que se producen sobre el Kernel, por lo que se tendrá una capa extra de software. Se necesita un conocimiento amplio del sistema, tanto los programadores como los administradores tienen que conocer el sistema para sacar el máximo rendimiento de él. No existe un programa que se ejecute de forma ideal en cualquier arquitectura ni configuración de cluster. Por lo tanto para paralelizar correcta y eficazmente se necesita que los programadores y administradores conozcan a fondo el sistema. El paralelismo es explícito, esto quiere decir que se programa de forma especial para poder usar las características especiales de PVM. Los programas deben ser reescritos. Si a esto se une que, como se necesita que los desarrolladores estén bien formados por lo anteriormente expuesto y que conozcan además PVM, se puede decir que migrar una aplicación a un sistema PVM no resulta económica (Ong & all, 2001). 2.3. MPI MPI es una especificación estándar para una librería de funciones de paso de mensajes. MPI fue desarrollado por el MPI Forum, un consorcio de vendedores de computadoras en paralelo, escritores de librerías y especialistas en aplicaciones. Consigue portabilidad proveyendo una librería de paso de mensajes estándar independiente de la plataforma y de dominio público. La especificación de esta librería está en una forma independiente del lenguaje y proporciona funciones para ser usadas con C y Fortran. Abstrae los sistemas operativos y el hardware. Hay implementaciones MPI en casi todas las computadoras y sistemas operativos. Esto significa que un programa paralelo escrito en C o Fortran usando MPI para el paso de mensajes, puede funcionar sin cambios en una gran variedad de Hardware y sistemas operativos. MPI sólo se ocupa de la capa de comunicación por paso de mensajes. Necesita un ambiente de programación paralelo nativo. Los procesos son creados cuando se carga el programa paralelo y están vivos hasta que el programa termina. Hay un grupo de procesos por defecto que consiste en esos procesos, identificado por MPI_COMM_WORLD. Los procesos MPI son procesos como se han considerado tradicionalmente, del tipo pesados, cada proceso tiene su propio espacio de direcciones, por lo que otros procesos no pueden acceder directamente a las variables del espacio de direcciones de otro proceso. La intercomunicación de procesos se hace vía paso de mensajes. 29 2. CLUSTER DE APLICACIÓN. Las desventajas de MPI son las mismas que se han citado en PVM, realmente son desventajas del modelo de paso de mensajes y de la implementación en espacio de usuario. Además aunque es un estándar y debería tener un API estándar, cada una de las implementaciones varía, no en las llamadas sino en el número de llamadas implementadas (MPI tiene unas 200 llamadas). Esto hace que en la práctica los diseñadores del sistema y los programadores tengan que conocer el sistema particular de MPI para sacar el máximo rendimiento. Además como sólo especifica el método de paso de mensajes, el resto del entorno puede ser totalmente distinto en cada implementación con lo que otra vez se impide esa portabilidad que en teoría se tiene (Gropp & all, 1996). 2.4. Beowulf El proyecto Beowulf este proyecto se basa en usar PVM y MPI, añadiendo algún programa más que se usan para monitorizar, realizar benchmarks y facilitar el manejo del cluster. Entre las posibilidades que integra este proyecto se encuentra la posibilidad de que se tengan equipos que no necesiten discos duros, por eso se consideran que no son un cluster de estaciones de trabajo, sino que dicen que pueden introducir nodos heterogéneos. Esta posibilidad la da otro programa y Beowulf lo añade a su distribución. Beowulf puede verse como un empaquetado de PVM/MPI junto con más software para facilitar el día a día del cluster pero no aporta realmente nada nuevo con respecto a tecnología (Beowulf,2003). 2.5. OpenMosix OpenMosix es un software para conseguir clustering en GNU/Linux, migrando los procesos de forma dinámica con requisa. Consiste en unos algoritmos de compartición de recursos adaptativos a nivel de Kernel, que están enfocados a conseguir alto rendimiento, escalabilidad con baja sobrecarga y un cluster fácil de utilizar. La idea es que los procesos colaboren de forma que parezca que están en un mismo nodo. Los algoritmos de openMosix son dinámicos lo que contrasta y es una fuerte ventaja frente a los algoritmos estáticos de PVM/MPI, responden a las variaciones en el uso de los recursos entre los nodos migrando procesos de un nodo a otro, con requisa y de forma transparente para el proceso, para balancear la carga y para evitar falta de memoria en un nodo. OpenMosix, al contrario que PVM/MPI, no necesita una adaptación de la aplicación ni siquiera que el usuario sepa nada sobre el cluster. Por otro lado openMosix puede balancear una única aplicación si esta está dividida en procesos lo que ocurre en gran número de aplicaciones hoy en día. Y también puede balancear las aplicaciones entre sí, lo que balancea openMosix son procesos, es la mínima unidad de balanceo. Cuando un nodo está muy cargado por sus 30 2. CLUSTER DE APLICACIÓN. procesos y otro no, se migran procesos del primer nodo al segundo. Con lo que openMosix se puede usar con todo el software actual si bien la división en procesos ayuda al balanceo gran cantidad del software de gran carga ya dispone de esta división. El usuario en PVM/MPI tiene que crear la computadora virtual decidiendo qué nodos del cluster usar para correr sus aplicaciones cada vez que las arranca y se debe conocer bastante bien la topología y características del cluster en general. Sin embargo en openMosix una vez que el administrador del sistema que es quien realmente conoce el sistema, lo ha instalado, cada usuario puede ejecutar sus aplicaciones y seguramente no descubra que se está balanceando la carga, simplemente verá que sus aplicaciones acabaron en un tiempo record. OpenMosix funciona a nivel de Kernel por tanto puede conseguir toda la información que necesite para decidir cómo está de cargado un sistema y qué pasos se deben seguir para aumentar el rendimiento, además puede realizar más funciones que cualquier aplicación a nivel de usuario, por ejemplo puede migrar procesos, lo que necesita una modificación de las estructuras del Kernel (miKel & Buytaert, 2004). 31 3. CLUSTER DE SISTEMA 3. CLUSTER DE SISTEMA 3.1. Introducción El concepto principal del clustering es poder contar con los recursos que puedan brindar el conjunto de computadoras con las que se cuenten. La unidad básica de un cluster es una computadora, también denominada nodo. Los cluster pueden escalar añadiendo computadoras. Un cluster como un todo puede ser más potente que la más veloz de las computadoras con las que se pueda contar, factor que esta ligado irremediablemente a la velocidad de conexión con la que se han construido las comunicaciones entre nodos. Así como el sistema operativo del cluster puede hacer un mejor uso del hardware disponible, teniendo como reto en un cluster diferentes arquitecturas (miKel & Buytaert, 2004). Básicamente existen tres tipos de clusters: Fail-over, Load-balancing y HIGH Performance Computing, los cuales se describen a continuación: . ! Cluster Fail-over. Consisten en dos o más computadoras conectadas en red con una conexión heartbeat separada entre ellas. La conexión heartbeat entre las computadoras es utilizada para monitorear cuál de los servicios está en uso, así como la sustitución de una computadora por otra cuando uno de sus servicios haya caído. ! Cluster Load-balancing. Se basa en que cuando haya una petición entrante al servidor web, el cluster verifica cuál de las computadoras disponibles posee mayores recursos libres, para luego asignarle el trabajo pertinente. Actualmente un cluster load-balancing es también fail-over con el extra del balanceo de la carga y a menudo con mayor número de nodos. ! Cluster High Performance Computing. Estas computadoras han estado configuradas especialmente para centros de datos que requieren una potencia de computación extrema. Los clusters Beowulf han sido diseñados específicamente para estas tareas de tipo masivo, teniendo en contrapartida otras limitaciones que no lo hacen tan accesible para el usuario como un openMosix (miKel & Buytaert, 2004). 32 3. CLUSTER DE SISTEMA 3.2. Mainframes, Supercomputadoras y Cluster Los Mainframes y las Supercomputadoras han estado construidas solamente por unos fabricantes muy concretos y para empresas o universidades que requieren gran potencia de cálculo. El costo económico que se tiene al adquirir un equipo de estas características, la mayoría de las veces supera las expectativas y esto hace que tome mayor importancia la idea de poder adquirir algún equivalente a un menor costo. El concepto de cluster nació cuando los pioneros de la supercomputación intentaban difundir diferentes procesos entre varias computadoras, para luego poder recoger los resultados que dichos procesos debían producir. Con un Hardware más barato y fácil de conseguir se pudo perfilar que podrían conseguirse resultados muy parecidos a los obtenidos con aquellas computadoras costosas. 3.3. De MOSIX a openMosix Primero fue MOSIX, ahora es openMosix, un proyecto que mejora los términos de la licencia GPL que mantenía a MOSIX bajo código propietario. OpenMosix es un parche (patch) para el kernel de linux que proporciona compatibilidad completa con el estándar de Linux para plataformas IA32. Actualmente se está trabajando para portarlo a IA64. El algoritmo interno de balanceo de carga para migrar los procesos entre los nodos, es transparente para el usuario. La principal ventaja es una mejor compartición de recursos entre nodos, así como un mejor aprovechamiento de los mismos. El cluster escoge por sí mismo la utilización óptima de los recursos que son necesarios en cada momento, y de forma automática. Esta característica de migración transparente hace que el cluster funcione para los efectos como un gran sistema SMP (Symmetric Multi Processing) con varios procesadores disponibles. El punto fuerte de openmosix es que intenta crear un estándar en el entorno del clustering para todo tipo de aplicaciones HPC. (miKel & Buytaert, 2004) 3.3.1. Características de openMosix ! Ventajas o No se requieren programas extras. o No son necesarias modificaciones en el código. 33 3. CLUSTER DE SISTEMA ! Desventajas o o o o o Es dependiente del kernel. No siempre migra los procesos, tiene limitaciones de funcionamiento. Problemas con memoria compartida. Los procesos con múltiples threads no se obtiene demasiada eficiencia. Cuando se ejecuta un solo proceso no hay mejora, por decir el navegador. OpenMosix se divide hasta hoy en cuatro subsistemas dentro del kernel, los subsistemas son: 1. Mosix File System (MFS) Permite un acceso a sistemas de archivos (FS) remotos (de cualquier otro nodo) si está localmente montado. El sistema de archivos deberán de ser montados en el directorio /mfs , de esta forma se podrá, acceder al directorio /home desde cualquier nodo del cluster. 2. Migración de procesos Con openMosix se puede lanzar un proceso en una computadora y ver si se ejecuta en otra. Cada proceso tiene su único nodo raíz (UHN, unique home node) que corresponde con el que lo ha generado. El concepto de migración significa que un proceso se divide en dos partes: la parte del usuario y la del sistema. La parte, o área, de usuario será movida al nodo remoto mientras el área de sistema espera en la raíz. OpenMosix se encargará de establecer la comunicación entre estos 2 procesos. 3. Direct File System Access (DFSA “Acceso de Sistema de Archivo directo”) OpenMosix proporciona MFS con las opciones DFSA que permite acceso a los sistemas de archivos, tanto locales como remotas. 4. Memory ushering ( Introduciendo Memoria) Este subsistema se encarga de migrar las tareas que superan la memoria disponible en el nodo en el que se ejecutan. Las tareas que superan dicho límite se migran forzosamente a un nodo destino de entre los nodos del cluster que tengan suficiente memoria como para ejecutar el proceso sin necesidad de hacer swap a disco, ahorrando así la gran pérdida de rendimiento que esto supone. 34 3. CLUSTER DE SISTEMA El subsistema de memory ushering es un subsistema independiente del subsistema de equilibrado de carga y por ello se le considera por separado (miKel & Buytaert, 2004). 3.3.2. Algoritmo de migración Las propiedades compartidas entre Mosix y openMosix se pueden considerar el mecanismo de migración, en el que puede migrarse cualquier proceso a cualquier nodo del cluster de forma completamente transparente al proceso migrado. La migración también puede ser automática: el algoritmo que lo implementa tiene una complejidad computacional del orden de O(n), siendo n el número de nodos del cluster. Para implementarlo openMosix utiliza el modelo fork-and-forget (tener y olvidar), desarrollado en un principio dentro de Mosix para computadoras PDP11/45 empleadas en las fuerzas aéreas norteamericanas. La idea de este modelo es que la distribución de tareas en el cluster la determina openMosix de forma dinámica, conforme se van creando tareas. Cuando un nodo está demasiado cargado y las tareas que se están ejecutando puedan migrar a cualquier otro nodo del cluster. Así desde que se ejecuta una tarea hasta que ésta muere, podrá migrar de un nodo a otro, sin que el proceso sufra mayores cambios (miKel & Buytaert, 2004). 3.3.3. El nodo raíz Cada proceso ejecutado en el cluster tiene un único nodo raíz. El nodo raíz es el nodo en el cual se lanza originalmente el proceso y donde éste empieza a ejecutarse. Desde el punto de vista del espacio de procesos de las computadoras del cluster, cada proceso (con su correspondiente PID) parece ejecutarse en su nodo raíz. El nodo de ejecución puede ser el nodo raíz u otro diferente, hecho que da lugar a que el proceso no use un PID del nodo de ejecución, sino que el proceso migrado se ejecutará en éste como una hebra del kernel. La interacción con un proceso, por ejemplo enviarle señales desde cualquier otro proceso migrado, se puede realizar exclusivamente desde el nodo raíz. El usuario que ejecuta un proceso en el cluster ha accedido al cluster desde el nodo raíz del proceso. El propietario del proceso en cuestión tendrá control en todo momento del mismo como si se ejecutara localmente. Por otra parte la migración y el retorno al nodo raíz de un proceso se puede realizar tanto desde el nodo raíz como desde el nodo dónde se ejecuta el proceso. Esta tarea la puede llevar a término el administrador de cualquiera de los dos sistemas (miKel & Buytaert, 2004). 35 3. CLUSTER DE SISTEMA 3.3.4. El mecanismo de migración La migración de procesos en openMosix es completamente transparente. Esto significa que al proceso migrado no se le avisa de que ya no se ejecuta en su nodo de origen. Es más, este proceso migrado seguirá ejecutándose como si siguiera en el nodo origen: si escribiera o leyera al disco, lo haría en el nodo origen, hecho que supone leer o grabar remotamente en este nodo. 3.3.5. ¿Cuándo podrá migrar un proceso? No todos los procesos pueden migrar en cualquiera circunstancia. El mecanismo de migración de procesos puede operar sobre cualquier tarea de un nodo sobre el que se cumplen algunas condiciones predeterminadas. Éstas son: ! El proceso no puede ejecutarse en modo de emulación VM86 ! El proceso no puede ejecutar instrucciones en ensamblador propias de la computadora donde se lanza y que no tiene la computadora destino (en un cluster heterogéneo) ! El proceso no puede mapear memoria de un dispositivo a la RAM, ni acceder directamente a los registros de un dispositivo ! El proceso no puede usar segmentos de memoria compartida Cumpliendo todas estas condiciones el proceso puede migrar y ejecutarse migrado. No obstante, openMosix no sabe si alguno de los procesos que pueden migrar tendrá algunos de estos problemas. Por esto en un principio openMosix migra los procesos que puedan hacerlo si por el momento cumplen todas las condiciones, y en caso de que algún proceso deje de cumplirlas, lo devuelve de nuevo a su nodo raíz para que se ejecute en él mientras no pueda migrar de nuevo. Todo esto significa que mientras el proceso esté en modo de emulación VM86, mapee memoria de un dispositivo RAM, acceda a un registro o tenga reservado/bloqueado un puntero a un segmento de memoria compartida, el proceso se ejecutará en el nodo raíz y cuando acabe la condición que lo bloquea volverá a migrar. Con el uso de instrucciones asociadas a procesadores no compatibles entre ellos, openMosix tiene un comportamiento diferente: solo permitirá migrar a los procesadores que tengan la misma arquitectura (Fink & Sherer, 2003). 3.3.6. La comunicación entre usuario y kernel Un aspecto importante es en cómo se realiza la comunicación entre el área de usuario y el área de kernel. 36 3. CLUSTER DE SISTEMA En algún momento, el proceso migrado puede necesitar hacer alguna llamada al sistema. Esta llamada se captura y se evalúa de 2 formas: ! Si puede ser ejecutada al nodo al que la tarea ha migrado, o ! Si necesita ser lanzada en el nodo raíz del proceso migrado Si la llamada puede ser lanzada al nodo dónde la tarea migrada se ejecuta, los accesos al kernel se hacen de forma local, es decir, que se atiende en el nodo dónde la tarea se ejecuta sin ninguna carga adicional a la red. Las llamadas más comunes son las que se han de ejecutar forzosamente al nodo raíz, puesto que hablan con el Hardware. Es el caso, por ejemplo, de una lectura o una escritura a disco. En este caso el subsistema de OpenMosix del nodo dónde se ejecuta la tarea contacta con el subsistema de OpenMosix del nodo raíz. Para enviarle la petición, así como los parámetros y los datos del nodo raíz que necesitará procesar. El nodo raíz procesará la llamada y enviará de vuelta al nodo dónde se está ejecutando realmente el proceso migrado: ! El valor del éxito/fracaso de la llamada ! Aquello que necesite saber para actualizar sus segmentos de datos, de pila y de heap ! El estado en el que estaría si se estuviera ejecutando el proceso al nodo raíz Esta comunicación también puede ser generada por el nodo raíz. Es el caso, por ejemplo, del envío de una señal. El subsistema de openMosix del nodo raíz contacta con el subsistema de openMosix del nodo dónde el proceso migrado se ejecuta y el avisa que ha ocurrido un evento asíncono. El subsistema de openMosix del nodo dónde el proceso migrado se ejecuta parará el proceso migrado y el nodo raíz podrá empezar a atender el código del área del kernel que correspondería a la señal asíncrona. Finalmente, una vez realizada toda el operativa necesaria de la área del kernel, el subsistema de openMosix del nodo raíz del proceso envía al nodo donde está ejecutándose realmente el proceso migrado el aviso detallado de la llamada y todo aquello que el proceso necesita saber cuando recibió la señal y el proceso migrado finalmente recuperará el control. Por todo esto el proceso migrado es como sí estuviera al nodo raíz y hubiera recibido la señal de éste. Se tiene un escenario muy simple donde el proceso se suspende esperando un recurso. La suspensión es esperando un recurso y se produce únicamente en el área de kernel. Cuando se pide una página de disco o se espera un paquete de red se resuelve como una llamada al kernel. Este mecanismo de comunicación entre áreas asegura que: ! La migración sea completamente transparente tanto para el proceso que migra como para los procesos que cohabiten con el nodo raíz ! Que el proceso no necesite ser reescrito para poder migrar, ni sea necesario conocer la topología del cluster para escribir una aplicación paralela 37 3. CLUSTER DE SISTEMA En el caso de llamadas al kernel que tengan que ser enviadas forzosamente al nodo raíz, se tendrá una sobrecarga adicional a la red debida a la transmisión constante de las llamadas al kernel y la recepción de sus valores de vuelta. Se destacan especialmente esta sobrecarga en el acceso a sockets y el acceso a disco duro, que son las dos operaciones más importantes que se habrán de ejecutar en el nodo raíz y suponen una sobrecarga al proceso de comunicación entre el área de usuario migrada y el área de kernel del proceso migrado (Fink & Sherer, 2003). 3.3.7. Instalación de un cluster openMosix La construcción física de un cluster openMosix es de la misma forma que un cluster Beowulf, pero para la construcción lógica (software) es distinta. La construcción de un cluster openMosix se compone de varios pasos: ! El primero es compilar e instalar un kernel con soporte openMosix ! El segundo, compilar e instalar las herramientas de área de usuario ! El tercer paso es configurar los demonios del sistema para que cada computadora del cluster siga el comportamiento que se espera ! El cuarto paso es crear el arch del mapa del cluster. Este cuarto paso sólo es necesario si no usamos la herramienta de autodetección de nodos (Sterling, 2001). 3.3.8. Instalación del kernel de openMosix El primer paso para instalar el kernel de openMosix es descargar el tarball. Una vez descargado el parche del kernel openMosix habrá que descomprimirlo: # gunzip openMosix-2.4.20-2.gz Después de descargar el parche openMosix, habrá que descargar el kernel de Linux. Se descarga el kernel correspondiente a la versión del parche que se ha descargado. Esto quiere decir que un parche 2.4.X-Y servirá para el kernel 2.4.X. Por ejemplo, el parche 2.4.20-2 sólo puede ser aplicado sobre el kernel 2.4.20. Una vez descargado el kernel de Linux se descomprime: # tar -zxf linux-2.4.20.tar.gz Se mueve el directorio donde se ha descomprimido el kernel a linux-openmosix: # mv linux-2.4.20 linux-openmosix 38 3. CLUSTER DE SISTEMA Y se aplica el parche de openMosix: patch openMosix-2.4.20-2, se entra en el directorio del kernel de Linux: # cd linux-openmosix Y se muestra el menú de configuración del kernel: # make menuconfig Para la configuración a través de menús con ncurses, ó para la configuración a través de X-Window (Sterling, 2001). # make xconfig 3.3.8.1. Opciones del kernel de openMosix El siguiente paso para configurar el kernel de openMosix es entrar en la opción openMosix -la primera opción del menú principal de la pantalla de configuración del kernel-. Allí se encontrara un menú con todas las opciones propias de openMosix. Estas opciones son: ! openMosix process migration support: Esta opción permite activar el soporte a la migración de procesos en openMosix. Esto incluye tanto la migración forzada por el administrador como la migración transparente automática de procesos, el algoritmo de equilibrado de carga y el Memory Ushering. Si no se activa esta opción, no se tendrá openMosix. ! Support clusters with a complex network topology: “topología compleja de red con clusters de apoyo”. Las computadoras que pertenecen al cluster openMosix pueden pertenecer a la misma red IP, estando conectadas por un hub o por un switch. En este caso, en openMosix se considera que la topología de la red es simple, lo que permite realizar algunas modificaciones en los algoritmos de cálculo de la función de costo del algoritmo de equilibrado de carga que hace más eficiente su cálculo. También mejora la eficiencia del algoritmo de colecta automática de información del cluster. Si se tienen todas las computadoras del cluster conectadas a través de hubs o switchs -es decir, que un paquete openMosix nunca necesitará pasar por un router- se puede aumentar sensiblemente el rendimiento del cluster desactivando esta opción. ! Maximum network-topology complexity to support (2-10): “Complejidad para apoyar niveles máximos de topologías de red”. Si se activa la opción anterior, aparecerá esta opción. En esta opción se pregunta cuantos niveles de complejidad hay entre las dos computadoras más lejanas del cluster, entendiendo por niveles de complejidad el número de routers intermedios más uno. Si se pone un número más alto de la cuenta, no se tendrá todo el 39 3. CLUSTER DE SISTEMA rendimiento que se podría tener en el cluster. Si se pone un número más bajo de la cuenta, no podrán verse entre sí las computadoras que tengan más routers intermedios que los indicados en este parámetro menos uno. ! Stricter security on openMosix ports: “Seguridad más estricta en puertos del openMosix”. Esta opción permite un chequeo adicional sobre los paquetes recibidos en el puerto de openMosix y unas comprobaciones adicionales del remitente. Aunque esto suponga una pequeña pérdida de rendimiento, permite evitar que mediante el envío de paquetes quebrantados se pueda colgar un nodo del cluster. De hecho, hasta hace poco tiempo se podía colgar un nodo del antiguo proyecto Mosix sólo haciéndole un escaneo de puertos UDP. Salvo que se tenga mucha seguridad en lo que se esta haciendo, se debe activar esta opción de compilación. ! Level of process-identity disclosure (0-3): “Nivelado de descubrimiento de proceso-identidad”. Este parámetro indica la información que va a tener el nodo de ejecución real de la tarea sobre el proceso remoto que está ejecutando. Aquí se debe destacar que esta información siempre estará disponible en el nodo raíz -en el nodo en el que se originó la tarea-; limitando la información sólo en el nodo en el que se ejecuta la tarea si este es distinto del nodo raíz. Este es un parámetro de compromiso: valores más bajos aseguran mayor privacidad, a cambio de complicar la administración. Valores más altos hacen más cómoda la administración del cluster y su uso, pero en algunos escenarios pueden violar la política de privacidad del departamento o de la empresa. Un 0 significa que el nodo remoto que ejecuta el proceso migrado no tiene ninguna información relativa al proceso migrado que se ejecuta en dicho nodo. Este modo hace la administración del cluster realmente complicada y no hay ninguna razón objetiva para recomendarlo. Un 1 significa que el nodo remoto que ejecuta el proceso migrado tiene como única información el PID del proceso. Este es un modo que permite al administrador del cluster saber qué es lo que está pasando en caso de problemas. Es un nodo útil cuando se usan computadoras no dedicadas que estén en los despachos de los usuarios del cluster y no se quieran tener protestas entre los usuarios del cluster sobre quién está haciendo más uso. Un 2 significa que el nodo remoto que ejecuta el proceso migrado conoce PID, el usuario propietario y el grupo propietario del proceso. Este es un modo útil en clusters dedicados y no dedicados cuando se sabe que no va a haber discusiones entre los usuarios porque alguien use los recursos del cluster más de la cuenta. Es una buena opción si se tienen nodos no dedicados en despachos de usuarios donde cualquier usuario no tiene cuentas en las computadoras de los otros, para asegurar una cantidad razonable de privacidad. Un 3 significa que en el nodo remoto que ejecuta el proceso migrado se tiene exactamente la misma información de los procesos migrados que de los procesos locales. Esto significa que para la información de los procesos el sistema se comporta realmente como un sistema SSI. Este modo es 40 3. CLUSTER DE SISTEMA recomendable en los escenarios donde los usuarios tienen cuentas en todas las computadoras del cluster, con lo que mantener la privacidad del espacio de procesos ya es de por si imposible y bloquear esta información solo complica el uso y la administración del cluster. Este es el escenario más habitual de uso de un cluster, por lo que en caso de dudas es mejor que se use este nivel de privacidad. De cualquier forma, cualquier proceso puede variar su nivel particular de privacidad grabando desde el propio proceso su nuevo nivel de privacidad en el archivo /proc/self/disclosure. ! Create the kernel with a -openmosix extension: “Creando el Kernel con una extensión de openMosix”. Si activamos esta opción, el nombre simbólico del kernel llevará la extensión -openMosix. Esto es importante a la hora de buscar y enlazar los módulos. Se Debe activar esta opción si, teniendo la misma versión de kernel base y de kernel para openMosix, se quiere que los módulos del kernel openMosix y los módulos del kernel antiguo no sean compartidos. Esto significa que si se activa esta opción se puede tener un kernel X.Y en el sistema y un kernel openMosix X.Y al mismo tiempo y que cada uno tendrá sus módulos por separado y guardados en directorios distintos. En principio, es una buena idea activar esta opción para evitar problemas de efectos laterales con un kernel ya existente en el sistema. ! openMosix File-System: “Sistema de Archivos openMosix”. Si se activa esta opción se puede usar el sistema de archivos oMFS, por lo que se debe activar esta opción sólo si se va a usar el oMFS. ! Poll/Select exceptions on pipes: “excepciones selectas de los pipes”. Esta opción es interesante, aunque separa a openMosix de una semántica SSI pura. En Unix, un proceso que escriba en un pipe en principio no es interrumpido si otro proceso abre el mismo pipe para leer o ya lo tenía abierto y lo cierra. Activando esta opción se separa de Posix: un proceso escritor en un pipe puede recibir una excepción cuando otro proceso abra un pipe para leer dicho pipe y puede recibir también una excepción si el pipe se queda sin lectores. Se activa el lanzamiento de la excepción de lectura del pipe con la llamada al kernel ioctl(pipefd, TCSBRK, 1) y se activa la señal de que el último lector ha cerrado el pipe con ioctl(pipefd, TCSBRK, 2). Por último, se puede tener una estimación aproximada de la cantidad de información que los procesos lectores han pedido leer de un pipe en particular con la llamada al sistema ioctl(pipefd, TIOCGWINSZ, 0). Esta llamada no da un valor exacto y puede equivocarse –puede suceder que solo de una estimación a la baja -. Por lo tanto, en caso de equivocación de la llamada, puede ser porque el proceso lector lee más de lo estimado. Aunque se active esta opción, por defecto, el envío de estas excepciones está desactivado para los procesos y cada proceso que quiera usar estas excepciones debe activar su posibilidad con ioctl. En principio no se activa esta opción, salvo que se quiera usar para programas propios. 41 3. CLUSTER DE SISTEMA ! Disable OOM Killer (NEW): “Inhabilitar el OOM Killer”. Las últimas versiones del kernel de Linux incluyen una característica bastante discutida: el OOM Killer. Esta opción permite inhabilitar el OOM Killer y evitar los problemas que este causa. En caso de duda, es recomendable habilitar esta opción -es decir, inhabilitar el OOM Killer-. Por último, los nodos del cluster deben tener el mismo tamaño máximo de memoria, o si no las tareas no migrarán. Para ello, entrar en la opción Processor type and features y en la opción High Memory Support se asigna el mismo valor a los nodos del cluster. Después de esto, el kernel estará listo para poder usar openMosix. Enseguida se seleccionan las opciones adicionales del kernel que coincidan con el Hardware instalado y el uso que le se le quiera dar a Linux, se graba la configuración y se escribe: # make dep Lo que calcula las dependencias entre partes del kernel -qué se compila y qué no se compila-. Después se limpia el kernel de restos de compilaciones anteriores, que pudieran tener una configuración distinta: # make clean Se compila el kernel: # make bzImage, Se compilan los módulos: make modules y se instalan los módulos: # make modules_install Posterior a esto se copila el nuevo kernel en el directorio /boot: cp arch/i386/boot/bzImage /boot/kernelopenMosix Por último, se tiene que crear una entrada en lilo.conf para el nuevo kernel; por ejemplo: image=/boot/kernelopenMosix label=om root=/dev/hda1 initrd=/boot/initrd.img append=" devfs=mount" read-only donde: /dev/hda1 es el dispositivo de bloques donde se encuentra el directorio raíz de Linux; se compila la tabla del LILO con el comando: # lilo Con esto se termina y el resultado es que se tiene un kernel listo para poder usarlo en un nodo openMosix. 42 3. CLUSTER DE SISTEMA En caso de presentar errores ver Anexo 2. Para conocer los pasos que se deben de seguir para configurar e instalar correctamente las herramientas de área de usuario, se puede ver a detalle el Anexo 3. y para conocer los errores frecuentes en la compilación e instalación de las herramientas, ver el Anexo 4. Una vez que ya se tiene instalado el kernel de openMosix, así como las utilidades de área de usuario de openMosix, lo que prosigue es configurar la topología del cluster, la cual se encuentra a detalle en Anexo 5. Ya que se ha configurado la topología del cluster, es importante conocer las características básicas necesarias que conforman a las herramientas de área de usuario, en donde se tratan puntos como: Monitoreando el cluster, Configurando los nodos en openMosix, Controlando los nodos con mosctl, Forzando migraciones, Recomendando nodos de ejecución y openMosixView; para ver en detalle en Anexo 6. (Sterling, 2001). Existen algunas técnicas que permiten optimizar el cluster, las cuales son descritas en el Anexo 7. 3.4. Administración del cluster El mantenimiento de un sistema resulta más delicado y costoso (en tiempo) que su correcta instalación. Es recomendable que sean probadas las herramientas, ya que pueden facilitar la detección de errores ó configuraciones. 3.4.1. Administración básica OpenMosix proporciona como principal ventaja la migración de procesos hacia aplicaciones HPC. El administrador puede configurar el cluster utilizando las herramientas de área de usuario de openMosix (openMosix-user-space-tools) ó editando la interfase que se encuentra en /proc/hpc. 3.4.2 Configuración Los valores en los ficheros del directorio /proc/hpc/admin presentan la configuración actual del cluster. El administrador del mismo puede configurar estos valores para cambiar la configuración en tiempo de ejecución, tal como se muestra en las tablas.3.1,!,3.5. 43 3. CLUSTER DE SISTEMA Tabla 3.1. Administración: Binarios en /proc/hpc/admin Bloquea la llegada de procesos remotos echo 1 /proc/hpc/admin/block Lleva los procesos a su nodo raíz echo 1 /proc/hpc/admin/bring Tabla3.2. Administración: Cambiando los parámetros en /proa/hpc Config El archivo de configuración principal (escrito por la utilidad setpe) Permite/prohíbe la llegada de procesos remotos Lleva los procesos a su nodo raíz Lista los actuales enlaces DFSA Block Bring Dfsalinks Tabla 3.3. Administración: Información de los otros nodos Clear Reinicia las estadísticas Cpujob Informa a openMosix que el ligado al procesador Informa a openMosix que el ligado a la E/S Informa a openMosix que estadísticas más lentamente Informa a openMosix que estadísticas más rápidamente Iojob Show Fase proceso está proceso está actualice las actualice las Tabla3.4. Administración: Escribiendo un '1' en /proc/hpc/decay /proc/[PID]/cantmove Razón por la cual el proceso ha sido migrado /proc/[PID]/goto A qué nodo el proceso podrá migrar /proc/[PID]/lock Si el proceso se ve bloquead en su nodo raíz /proc/[PID]/nmigs El numero de veces que el proceso ha migrado /proc/[PID]/where Donde el proceso se computado actualmente /proc/[PID]/migarte Same as goto remote processes /proc/hpc/remote/from El nodo raíz del proceso /proc/hpc/remote/identity Información adicional del proceso 44 encuentra siendo 3. CLUSTER DE SISTEMA /proc/hpc/remote/statu Estadística de memoria del proceso /proa/hpc/remote/stats Estadística del procesador del proceso Tabla3.5. Administración: Información adicional sobre los procesos locales /proc/hpc/nodes/[openMosix_ID]/CPUs El número de CPUs que posee el nodo /proc/hpc/nodes/[openMosix_ID]/load La carga de openMosix en este nodo /proc/hpc/nodes/[openMosix_ID]/mem Memoria disponible para openMosix /proc/hpc/nodes/[openMosix_ID]/rmem Memoria disponible para Linux /proc/hpc/nodes/[openMosix_ID]/speed Velocidad del nodo relativa a un PIII/1GHz /proc/hpc/nodes/[openMosix_ID]/status Estado del nodo /proc/hpc/nodes/[openMosix_ID]/tmem Memoria disponible /proc/hpc/nodes/[openMosix_ID]/util Utilización del nodo 3.4.3. Las herramientas de área de usuario Estas herramientas permitirán un fácil manejo del cluster openMosix. A continuación se listan sus parámetros: migrate [PID] [openMosix_ID] envía una petición de migrado del proceso identificado con el ID, al nodo que se indique. mon es un monitor de los daemons basado en el terminal y da información relevante sobre el estado actual que puede ser visualizada en diagramas de barras. mosctl es la principal utilidad para la configuración de openMosix. Su sintaxis se explica en la tabla 3.6. mosctl [stay|nostay] [block|noblock] [quiet|noquiet] [nomfs|mfs] [expel|bring] [gettune|getyard|getdecay] mosct whois [openMosix_ID|IP-address|hostname] 45 3. CLUSTER DE SISTEMA mosct [getload|getspeed|status|isup|getmem|getfree|getutil] [openMosix_ID] mosctl setyard [Processor-Type|openMosix_ID||this] mosctlsetspeed interger-value mosctlsetdecay interval [slow fast] Tabla3.6. Administración: Parámetros adicionales para mosrun stay nostay lstay nolstay block v quiet noquiet nomfs mfs expel bring gettune getyard getdecay whois Desactiva la migración automática Migración automática (defecto) Local processes should stay Los procesos locales podrán migrar Bloquea la llegada de otros procesos Permite la llegada de procesos Desactiva la posibilidad de dar información sobre la carga del nodo Activa la posibilidad de dar información sobre la carga del nodo Desactiva MFS Activa MFS Envía fuera del nodo los procesos que han llegado previamente Traerá los procesos migrados hacia su nodo raíz Muestra el parámetro de overhead Muestra la utilización actual de Yardstick Muestra el estado del parámetro decay Nos muestra el openMosix-ID, la dirección IP y los nombres de host del cluster getload Muestra la carga (openMosix-) getspeed Muestra la velocidad (openMosix-) status Muestra el estado y la configuración actual isup Nos informa de si un nodo está funcionando o no (ping openMosix) getmem Muestra la memoria lógica libre getfree Muestra la memoria física libre getfree Muestra la utilización del nodo setyard Establece un nuevo valor para Yardstick setspeed Establece un nuevo valor para la velocidad (openMosix-) setdecay Establece un nuevo valor para el intervalo del decay Con mosrun se ejecutara un comando especialmente configurado en un nodo establecido. sintaxis: mosrun[-h|openMosix_ID|list_of_openMosix_IDs] command [arguments] El comando mosrun puede ser ejecutado con diversas opciones. Para evitar complicaciones innecesarias viene con ciertas pre configuraciones para ejecutar las tareas con configuraciones especiales de openMosix. Tabla 3.7. 46 3. CLUSTER DE SISTEMA Tabla3.7. Administración: Parámetros de mosctl con más detalle Nomig Runhome Runon Runs a command which process(es) won't migrate Ejecuta un comando bloqueado en el nodo raíz Ejecutará un comando el cuál será directamente migrado y bloqueado a cierto nodo Informa a openMosix que el proceso está ligado a la CPU Informa a openMosix que el proceso está ligado a la E/S Ejecuta un comando e informa al cluster de no refrescar las estadísticas de carga Ejecuta un comando con intervalo de decay grande para acumular en las estadísticas Ejecuta un comando con intervalo de decay pequeño para acumular en las estadísticas Cpujob Iojob Nodecay Slowdecay Fastdecay ! setpe es una utilidad de configuración manual del nodo sintaxis: setpe setpe setpe -w -f -r [-f -off [hpc_map] [hpc_map]] ! -w lee la configuración de openMosix desde un archivo (normalmente /etc/hpc.map). ! -r escribe la configuración actual de openMosix en un archivo (normalmente /etc/hpc.map). ! -off desactiva la configuración actual del cluster. Existen utilidades adicionales a la interfície de /proc y a las líneas de comandos. Por ejemplo existen unos parches para ps y para top (llamados mps y mtop) los cuales muestran adicionalmente el ID del nodo openMosix en una columna. Esta posibilidad es interesante para encontrar dónde ha migrado un cierto proceso (miKel & Buytaert, 2004). 3.4.4. Detección automática de nodos El demonio de auto detección de nodos, omdiscd, proporciona un camino automático para la configuración del cluster openMosix. Con él se podrá eliminar la necesidad de configuraciones manuales como son la edición del archivo /etc/mosix.map omdiscd genera un envío de paquetes multicast (a todas las direcciones, en este caso, nodos) para notificar a los otros nodos que se ha añadido uno nuevo. Esto significa que al añadir un nodo sólo se tendrá que iniciar omdiscd en él. Se debe tener en cuenta hacer una configuración de la red de interconexión de los nodos, en especial para el correcto enrutamiento de paquetes, especificar una ruta por defecto omdiscd. 47 3. CLUSTER DE SISTEMA Un ejemplo cuando se tiene una configuración aceptada podría ser: [root@localhost log]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref 10.0.0.0 127.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 10.0.0.99 255.0.0.0 255.0.0.0 0.0.0.0 U U UG 0 0 0 Use Iface 0 0 0 0 eth0 0 lo 0 eth0 La importancia de poder automatizar el reconocimiento de nuevos nodos conectados al sistema ha facilitado que se llegue a la simplicidad con la que se cuenta actualmente para iniciar dicha detección, con el comando omdiscd. Observando lo que produce logfiles se tendría que ver algo parecido a: May 3 10:00:49 rene03 kernel: openMosix openMosix #2780 of 6 configured) May 3 10:00:49 rene03 kernel: openMosix #2780 May 3 0:00:49 rene03 kernel: openMosix #2638 May 3 10:00:49 rene03 kernel: openMosix #2646 May 3 0:00:49 rene03 kernel: openMosix #2627 May 3 10:00:49 rene03 kernel: openMosix #2634 configuration is is is is is at at at at at IP IP IP IP IP changed: address address address address address This is 192.168.0.30 192.168.0.25 192.168.0.20 192.168.10.15 192.168.0.10 Se tendrá el cluster listo para ser utilizado. omdiscd tiene otras opciones entre las que cuentan poder ejecutarse como un demonio (por defecto) ó en background (segundo plano) donde la salida será la pantalla (la salida estándar), con el comando omdiscd -n. La interfase, debe ser especificada con la opción -i. La herramienta showmap. Esta utilidad mostrará el nuevo mapa, de la forma siguiente: [root@oscar0 root]# showmap My Node-Id: 0x0adc Base Node-Id -----------0x0adc 0x0a4e 0x0a56 0x0a43 0x0a4a Address Count ---------------- ----192.168.0.30 1 192.168.0.25 1 192.168.0.20 1 192.168.0.15 1 192.168.0.10 1 Para conocer las distintas utilidades que pueden ser útiles para la detección automática de nodos, como un mecanismo de routing para clusters con más de una red de conexión, se pueden encontrar en los README y DESIGN de las herramientas de usuario (miKel & Buytaert, 2004). 48 3. CLUSTER DE SISTEMA 3.4.5. Compilaciones Si se quiere obtener este módulo a partir de las fuentes se tendrá que hacer una pequeña modificación en el archivo openmosix.c. Una de las líneas, concretamente #define ALPHA se tendrá que comentar ya que se esta trabajando en plataforma x86. Si se quisiera tener un historial más detallado se edita main.c para escribir: log_set_debug(DEBUG_TRACE_ALL); (En la línea 84 aproximadamente) posteriormente se ejecuta: make clean make 3.4.6. Problemas Algunas veces la auto-detección no funcionará tal como se espera, por ejemplo cuando un nodo debería ser detectado y no ve el tráfico multicast que se lleva a cabo en la red. Esto ocurre con algunas tarjetas PCMCIA. Una solución posible sería poner la interfase en modo promíscuo, tal como se detalla a cotinuación: Aug 31 20:45:58 localhost kernel: openMosix configuration changed: This is openMosix #98 (of 1 configured) Aug 31 20:45:58 localhost kernel: openMosix #98 is at IP address 10.0.0.98 Aug 31 20:45:58 localhost omdiscd[1627]: Notified kernel to activate openMosix Aug 31 20:45:58 localhost kernel: Received an unauthorized information request from 10.0.0.99 Algo que se puede probar es forzar manualmente el NIC a modo promiscuo y/o multicast, así: ifconfig ethx promisc ó ifconfig ethx multicast, Se podrá ejecutar igualmente tcpdump -i eth0 ether multicast Si se muestra simulated es que no sea puesto el comentario a la línea: #define ALPHA, sería: Aug 31 22:14:43 inspon omdiscd[1422]: Simulated notification to activate openMosix [root@inspon root]# showmap My Node-Id: 0x0063 Base Node-Id Address Count ------------ ---------------- ----0x0063 10.0.0.99 1 [root@inspon root]# /etc/init.d/openmosix status OpenMosix is currently disabled [root@inspon root]# 49 3. CLUSTER DE SISTEMA 3.5. Testeo de rendimiento con Stress-Test A continuación se describe de forma general y detallada la función principal del StressTest, el cual permitirá evaluar la aplicación que se instalo, esto con el único propósito de poder cuantificar los procesos ejecutados. 3.5.1. Descripción general Este stress-test está hecho para evaluar un cluster openMosix. Realizará diversas evaluaciones a sus aplicaciones y a su kernel, para testear la estabilidad y la migración de procesos MFS con openMosix. Durante este test el cluster se verá sobrecargado, es por eso que se sugiere detener cualquier otra aplicación que se tenga corriendo antes de iniciarlo. Al finalizar se generará un reporte detallado acerca de cada componente que ha sido evaluado (miKel & Buytaert, 2004). 3.5.2. Descripción detallada Stress-Test corre una cantidad importante de programas para evaluar la funcionalidad de todo el sistema. En el Anexo 8, se listan una serie de descripciones de cada test. 3.5.3. openMosixview Es una interfase gráfica (GUI) libre para la administración y mantenimiento de un cluster openMosix que se puede bajar de la web (miKel & Buytaert, 2004). La suite openMosixview contiene 7 aplicaciones útiles tanto para la administración como para la monitorización del cluster. ! openMosixview. Principal aplicación de monitorización y administración. ! openMosixprocs. Aplicación para la administración de procesos. ! openMosixcollector. Captura la información del cluster proporcionada por los demonios. ! openMosixanalyzer. Analizador de la información capturada por openMosixcollector. ! openMosixhistory. Historial de monitorización de procesos del cluster. ! openMosixmigmon. Visor que representa la migración de procesos. ! 3dmosmon. Visor para monitorización de datos en 3D. Los componentes son accesibles desde la ventana de la aplicación principal. 3.5.3.1. Instalación Requerimientos: ! Tener instaladas las librerías QT según marque la versión, ! Derechos de superusuario -root-, ! Las herramientas de usuario de openMosix -userland-tools-. 50 3. CLUSTER DE SISTEMA 3.5.3.2. Instalación desde paquetes RPM Los paquetes RPM tienen como directorio de instalación la ruta /usr/local/ openMosixviewversión . Tras bajar la última versión de los paquetes RPM de openMosixview, habrá que instalarlos como cualquier otro paquete, sea desde línea de comandos: rpm -i openMosixview- versión - distribución .rpm Lo anterior instalará los archivos binarios en el directorio /usr/bin/. Para desinstalarlos se ejecuta: rpm -e openMosixview 3.5.3.3. Instalación desde las fuentes Con la versión en forma de tarball se descomprime con -y se desempaqueta así: tar -zxvf openMosixview- versión .tar.gz 3.5.3.4. Script de configuración automático Sólo será necesario entrar al directorio openMosixview y ejecutar: ./setup [directorio_de_instalación_qt_ versión ] 3.5.3.5. Compilación manual Será necesario situar la variable QTDIR hacia el directorio de la distribución QT, por ejemplo: export QTDIR=/usr/lib/qt-2.3.0 (para bash) ó setenv QTDIR /usr/lib/qt-2.3.0 (para csh) Tras lo cual tendría que ejecutar con éxito la configuración y la compilación: ./configure make Luego será necesario hacer lo mismo en los subdirectorios de openMosixcollector, openMosixanalyzer, openMosixhistory y openMosixviewprocs, para poder disponer de 51 3. CLUSTER DE SISTEMA los binarios ejecutables de estas aplicaciones. Tras este procedimiento se copiaran los binarios a /usr/bin/ siguiendo: cp openMosixview/openMosixview /usr/bin cp openMosixviewproc/openMosixviewprocs/mosixviewprocs /usr/bin cp openMosixcollector/openMosixcollector/openMosixcollector /usr/bin cp openMosixanalyzer/openMosixanalyzer/openMosixanalyzer /usr/bin cp openMosixhistory/openMosixhistory/openMosixhistory /usr/bin y el script de iniciación de openMosixcollector en el directorio de iniciación: cp openMosixcollector/openMosixcollector.init /etc/init.d/openMosixcollector Si se quiere que estas aplicaciones de monitorización se ejecuten localmente en cualquier nodo, se tendrán que copiar los binarios a cada nodo del cluster en su directorio /usr/bin/ 3.6. Utilizando openMosixview La herramienta que a continuación se describe, permitirá mostrar de forma gráfica los trabajos que se ejecuten cuando el cluster se encuentre en proceso, logrando con ello un control más idóneo para el mismo cluster. 3.6.1. Aplicación principal La Figura 3.1. Muestra la ventana de la aplicación. El usuario podrá interaccionar con el API de openMosix a través de sus controles. Para cada nodo del cluster -cada fila-: una luz, un botón, un speed-slider, un número lcd, dos barras de progreso porcentual y un par de etiquetas. Figura 3.1. openMosixview: Aplicación principal Las luces de la izquierda muestran el ID del nodo y su estado. El fondo rojo significa que el nodo no se encuentra operativo y verde lo contrario. 52 3. CLUSTER DE SISTEMA Si se hace clic en el botón que muestra la dirección IP de un nodo se habrá llamado al diálogo de configuración que mostrará los botones para ejecutar los comandos de mosctl más comunes. Con los speed-sliders se establece la velocidad que considerará el cluster para cada nodo. Este parámetro se muestra numéricamente en el display lcd (de la derecha). Todo ajuste tendrá efectos directos sobre el algoritmo de balanceo de carga de openMosix, intervienen en la ponderación de velocidad que se debe considerar para cada nodo. De esta manera los procesos migrarán más fácilmente hacia un nodo cuya velocidad sea más elevada. Las barras de progreso dan una idea general de la carga de cada nodo del cluster. La primera se refiere a la carga del procesador y muestra un porcentaje que será una aproximación del valor escrito por openMosix en el archivo /proc/hpc/nodes/x/load. La segunda barra muestra la memoria utilizada en cada nodo. El box de la izquierda muestra el total de memoria -en megabytes- que posee cada nodo. Finalmente el último box muestra el número de procesadores de cada nodo. Hasta ahora se ha definido la interfaz para cada nodo en particular, no obstante la misma aplicación muestra información general del cluster. El box load-balancing efficiency es un indicador de la eficiencia del algoritmo de balanceo de carga. Un valor próximo al 100% indica que la carga computacional ha podido dividirse equitativamente entre los nodos; este es el fin que persigue openMosix. Bajo la barra de menús existen varios iconos que lanzan las demás aplicaciones del entorno openMosixview. Se pueden utilizar los menús de collector- y analyzer- para administrar openMosixcollector y openMosixanalyzer, respectivamente. 3.6.2. La ventana de configuración Esta ventana emergente de la Figura 3.2, aparecerá tras hacer clic en el botón de la IP de cualquier nodo, permite una fácil configuración de la computadora con dicha dirección. Los comandos de esta ventana se ejecutan a través de rsh o ssh en los nodos remotos y en el local, siendo root. 53 3. CLUSTER DE SISTEMA Figura3.2. openMosixview: Propiedades de los nodos Si hay instalado openMosixprocs en los nodos remotos del cluster se podrá dar clic en el botón remote proc-box para llamar openMosixprocs remotamente. Se mostrará en pantalla los parámetros [xhost+hostname] y serán configurados para apuntar al nodo local. Además el cliente es ejecutado en el remoto con rsh o ssh. openMosixprocs permitirá una administración de programas. Se ha tenido la oportunidad para entrar desde una estación de trabajo remota se podra introducir el nombre del nodo local en la edit-box, debajo de la remote proc-box. Luego openMosixprocs se nos mostrará en nuestra estación de trabajo y no en el nodo del cluster donde hemos entrado (podemos configurar [xhost+clusternode] en nuestra estación de trabajo). Podemos encontrar un historial en el combo-box así como el nombre de nodo que hayamos escrito (miKel & Buytaert, 2004). 3.6.3. Ejecución avanzada Si se quieren iniciar trabajos en el cluster el diálogo de advanced execution mostrado en la Figura 3.3 podrá ayudar para convertirlo a modo gráfico. Se elige el programa a iniciar con el botón run-prog (en File-Open-Icon) y se especifica cual y donde se encuentra el trabajo que se quiere iniciar en este dialogo de ejecución. 54 3. CLUSTER DE SISTEMA 3.6.4. La línea de comandos En la tabla 3.8., se describen los argumentos a los que se pueden acceder de forma grafica a través de de comandos en el lineedit-widget en la parte superior de la ventana, tal como se muestra en la Figura 3.3. Figura 3.3. openMosixview: Ejecución avanzada Tabla 3.8. openMosixview: Condiciones de inicio avanzadas para procesos No migration Iniciar un proceso local que no migrará run home Iniciar un proceso local run on Iniciar un trabajo en el nodo que elijamos con "nodo-chooser" cpu job Iniciar un proceso cpu-intensivo en el nodo (nodo-chooser) io job Iniciar un proceso IO-intensivo en el nodo (nodo-chooser) no decay Iniciar un proceso sin decay (nodo-chooser) slow decay Iniciar un proceso con decay lento (nodo-chooser) fast decay Iniciar un proceso con decay rápido (nodo-chooser) Parallel Iniciar un proceso paralelo en todos o algunos nodos (special nodo-chooser) 55 3. CLUSTER DE SISTEMA 3.6.4.1. El host-chooser Para todas las tareas que se ejecuten de manera remota sólo se tiene que elegir un nodo que la hospede con el dial-widget. El ID de openMosix del nodo se muestra también en forma de lcd. Luego se pulsa execute para iniciar el trabajo. 3.6.4.2. El host-chooser paralelo Se podrán configurar el primer y el último nodo con 2 spinboxes. Luego el comando será ejecutado en los nodos, desde el primero hasta el último y viceversa. 3.6.5. openMosixprocs La ventana de procesos que se muestra en la Figura 3.4. es muy útil para la administración de los procesos de cluster. Se sugiere que se instale esta aplicación en cada nodo. La lista de procesos proporciona una idea de lo que se está ejecutando y donde se ejecuta. La segunda columna informa del ID del nodo donde se está ejecutando la tarea. Con un doble clic sobre cualquier proceso se invoca la ventana para administrar su migración (siguiente figura 3.5). Un '0' significa 'local', los demás valores significan 'remoto'. Los procesos migrados están marcados con un icono verde y a los procesos que no pueden migrar se les añade un cerradero. Hay también varias opciones para migrar el proceso remoto: enviarle las señales SIGSTOP y SIGCONT o simplemente cambiarle la prioridad, con el comando nice por dar un ejemplo. Si se hace clic en el botón manage procs from remote se invocara a una ventana emergente (llamada remote-procs windows) que mostrará el proceso actualmente migrado hacia ese nodo (miKel & Buytaert, 2004). 3.6.5.1. La ventana de migración La Figura 3.5 emergerá si se hace clic sobre cualquier proceso en la figura 3.4 anterior. La ventana openMosixview-migrator muestra los nodos de nuestro cluster, arriba a la izquierda. Esta ventana sirve para administrar un proceso (con información adicional). Al hace doble clic en un nodo migrará a este nodo. Tras breves instantes el icono del proceso cambiará a verde, lo que significa que está siendo ejecutado remotamente. 56 3. CLUSTER DE SISTEMA El botón home envía un proceso a su nodo raíz. Con el botón best el proceso será enviado hacia el mejor nodo disponible en el cluster. Figura 3.4. openMosixprocs: Administración de procesos Esta migración se ve influenciada por la carga, velocidad, número de procesadores y su mayor o menor velocidad. Con el botón kill se mata al proceso. Para pausar un programa sólo se tendrá que pulsar en el botón etiquetado como SIGSTOP y para reanudarlo, en SIGCONT. Con el slider de renice se puede cambiar la prioridad de los procesos para una administración más completa, así el valor -20 se traduce en una mayor prioridad para terminar el trabajo, 0 le da prioridad normal y 20 le sitúa en una prioridad muy baja para tratarlo (miKel & Buytaert, 2004). Figura 3.5. openMosixprocs: La ventana de migrado de un proceso (1) 57 3. CLUSTER DE SISTEMA 3.6.5.2. Administrando procesos remotamente El diálogo mostrado en la Figura 3.6 aparecerá si se hace clic en el botón manage procs from remote. Las pestañas muestran los procesos que han migrado al nodo local. De forma parecida a los 2 botones en la ventana de migrado, el proceso será enviado a su nodo raíz si pulsamos goto home node y enviado al mejor nodo si pulsamos goto best node. Figura 3.6. openMosixprocs: La ventana de migrado de un proceso (2) 3.6.6. openMosixcollector openMosixcollector es un daemon (demonio) que debe y/o puede ser invocado desde cualquier miembro del cluster. Genera un historial de la carga de cada nodo del cluster al directorio /tmp/openMosixcollector/*. Este historial puede servir de entrada para openMosixanalyser para ofrecer una vista general de la carga, memoria y procesos en nuestro nodo durante un intervalo de tiempo. Existe otro historial principal llamado /tmp/openMosixcollector/cluster Y adicionalmente a éstos existen archivos en los directorios donde se escriben los datos. Al iniciar, openMosixcollector escribe su PID en /var/run/openMosixcollector.pid El demonio de openMosixcollector reinicia cada 12 horas y guarda el actual historial a /tmp/openMosixcollector[date]/* Estos backups se hacen automáticamente pero también se pueden hacer manualmente. Hay una opción que permite escribir un checkpoint al historial. Estos checkpoints se pueden ver gráficamente como una fina línea azul vertical si se analiza el historial con 58 3. CLUSTER DE SISTEMA openMosixanalyser. Por ejemplo se puede poder un checkpoint cuando se inicia cierto trabajo en el cluster y otro cuando éste finaliza. Aquí tenemos una referencia de los posibles argumentos para la consola: openMosixcollector openMosixcollector openMosixcollector openMosixcollector openMosixcollector -d //inicia el collector como un daemon -k //detiene el collector -n //escribe un checkpoint en el historial -r //guarda el actual historial y empieza uno de nuevo //saca por la salida estándar una ayuda rápida Se puede iniciar este demonio con su script de iniciación, que se encuentra en /etc/init.d o en /etc/rc.d/init.d 3.6.7. openMosixanalyzer La herramienta que a continuación se describe, tiene como objetivo almacenar un historial el cual puede ser observado de forma gráfica. 3.6.7.1. Una visión general de la carga del sistema La siguiente figura 3.7, muestra de forma gráfica la carga en el openMosixanalyzer. Con el openMosixanalyzer se tendrá un historial contínuo del cluster. Los historiales generados por openMosixcollector se mostrarán ahora de forma gráfica, además de forma contínua, lo que permitirá ver la evolución del rendimiento y demás parámetros del cluster a través del tiempo. openMosixanalyzer puede analizar los historiales a tiempo real (datos generados a tiempo real) y también puede abrir antiguos backups con el menú File. Los historiales serán guardados en /tmp/openMosixcollector/* (y los backups se encontraran en /tmp/openMosixcollector[date]/*) y sólo se tendrá que abrir el historial principal del cluster para visualizar antiguos historiales de informaciones de carga. (el campo [date] en los archivos de backup se refiere a la fecha en que han sido guardados) La hora de inicio del backup puede verse en la parte superior de la pantalla como se puede observar en la figura 3.7. Si se utiliza openMosixanalyzer para tratar historiales a tiempo real se tendrá que activar el check refresh para que se actualice automáticamente. Las líneas que indican la carga son normalmente de color negro. Si la carga se incrementa a 75 las líneas se volverán rojas. Estos valores se obtienen desde los archivos /proc/hpc/nodes/[openMosix ID]/* 59 3. CLUSTER DE SISTEMA Figura 3.7. openMosixanalyzer. Historial de actividad de procesamiento del cluster El botón Find-out de cada nodo calcula diversos valores para las estadísticas. Si se hace clic se abre una nueva ventana en la cual se verán las medias de la carga, memoria y algunas informaciones adicionales (estáticas y dinámicas) sobre el nodo en concreto. 3.6.7.2. Estadísticas sobre los nodos del cluster Si hay checkpoints escritos en el historial (generado por openMosixcollector) se podrán verlos traducidos como líneas azules verticales. Esto permite comparar valores de carga a posteriori de forma fácil. Véase la Figura 3.8. Figura 3.8. openMosixanalyzer. Estadísticas de los nodos 3.6.7.3. Monitorización de la memoria La Figura 3.9 muestra las gráficas de memoria proporcionadas por openMosixanalyzer. La filosofía de monitorización de la memoria es idéntica a la explicada anteriormente con la carga y evidentemente sirven también para poder ver como se ha comportado openMosix para administrar los recursos de memoria, en este caso. Para mostrar sus gráficas, openMosixnalyzer obtiene información de estos archivos /proc/hpc/nodes/[openMosix-ID]/mem. /proc/hpc/nodes/[openMosix-ID]/rmem. /proc/hpc/nodes/[openMosix-ID]/tmem. 60 3. CLUSTER DE SISTEMA Los checkpoints se muestran de igual forma que en la carga, con fina líneas verticales de color azul. Figura 3.9. openMosixanalyzer. Historial de actividad de memoria de nuestro cluster 3.6.7.4. openMosixhistory Con openMosixhistory se puede acceder a la lista de procesos ejecutados en el pasado, ver Figura 3.10; se consigue una lista de los procesos que se ejecutaron en cada nodo. openMosixcollector guarda la lista de procesos de cada nodo cuando se inicia y con el openMosixhistory se puede navegar en dicha información para ver el comportamiento que desarrolló el cluster. Se puede cambiar fácilmente el tiempo de navegación con un slider situado en la parte superior, para así ajustar la ventana del pasado. openMosixhistory puede analizar en tiempo real los historiales y también abrir antiguos de forma idéntica. Los historiales se obtienen nuevamente de /tmp/openMosixcollector/* y sólo se tendrá que abrir el historial principal para poder navegar en los archivos de información sobre la carga dada tiempo atrás (miKel & Buytaert, 2004). Figura 3.10. openMosixhistory. Un historial de los procesos ejecutados 61 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERÍA. 4.1. Hardware requerido Para llevar a cabo la implantación del cluster, se realizo la instalación en red de 3 computadoras, con las siguientes características: • • • • • Procesador Pentium IV a 2.0 GHZ Intel Memoria principal de 256 MB Disco duro de 40 GB, Monitor de 15 pulgadas, Tarjeta de Red Todo lo anterior de marca Compaq modelo EVO serie 5500. En la figura 4.1 se observan las computadoras utilizadas, Figura. 4.1. Equipo individual. (a) y (b) En la figura 4.2 se presentan los equipos instalados. Figura. 4.2. Equipos instalados (a) y (b) Los equipos contaron con conectividad a red, usando cableado UTP de categoría 5e, conectados a un switch de 8 puertos (Figura 4.3.(a) y (b)), así como imágenes que 62 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. muestran la parte trasera de los equipos de donde se conecta el RJ45 (Figura 4.3. (c) y (d)). Figura. 4.3. swhitch con capacidad para comunicar hasta 8 nodos. (a) y (b) Figura. 4.3. Vista de conexiones de los equipos utilizados (c) y (d) 4.2. Software utilizado Se instalo en los tres equipos sistema operativo Red Hat en su versión 9.0; a los cuales se les modifico el kernel, ya que se instalo la herramienta openMosix; creando un menú de arranque para que se pudiera decidir si se trabajaba utilizando el sistema tal y como se había instalado o utilizando el sistema con la modificación agregada con openMosix. Ver figura 4.4. (a) y (b) (a) muestra el menú a ser seleccionado (b) clave de acceso. Figura. 4.4. Software utilizado (a) y (b). 63 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. 4.3. Herramientas que se utilizan en los cluster Una de las prioridades que siempre se ha tenido es la producción de software en su categoría de libre; en México hay una pagina en donde se encuentran listados varios programas que cumplen con esta categoría, la URL es la siguiente: http://www.fisica.uson.mx/carlos/Software/; es aquí donde se define el concepto de software libre, que se caracteriza por promover las siguientes libertades y obligaciones al usuario final y a los desarrolladores: ! Libertad de ser utilizado por cualquier persona para cualquier propósito. ! Libertad de ser copiado y distribuido libremente (se le puede pasar al vecino sin ningún problema). ! Libertad de estudiarlo (para esto es indispensable contar con el código fuente) ! Libertad de modificarlo. A continuación se listaran las ubicaciones de algunos proyectos donde se aplica el concepto de Software Libre y de Fuente Abierta: Proyecto GNU Fundación para el software libre URL: http://www.gnu.org/home.es.html el software libre en URL: http:www.gnu.org/directory/ FSF Europe Fundación Software Libre Europa. URL: http://fsfeurope.org/index.es.html SourceForge.net. Sitio Web más grande del mundo de desarrollo de Software de Fuente Abierta, que hospeda más de 91,000 proyectos. La misión de SourceForge es la de proveer un sitio central para la coordinación del desarrollo de proyectos de Fuente Abierta. URL: http://sourceforge.net/ y el software se puede tener disponible desde: URL: http://sourceforge.net/softwaremap/trove_list.php The OpenCD Project. El proyecto TheOpenCD es una colección de Software de Fuente Abierta. Los programas corren en Windows y cubren las tareas más comunes como son lo de procesamiento de palabras, presentaciones, correo electrónico, navegadores de Web, diseño Web, y manipulación de imágenes. URL: http:// theopencd.sunsite.dk/ 64 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. Proyecto WinSLow. es un proyecto liderado por la asociación Aditel que persigue dos objetivos fundamentales URL:http://winslow.aditel.org/ ! Crear un repositorio de programas libres que funcionen sobre Windows ! Distribuir dicho repositorio en un CD Las aplicaciones incluidas en el repositorio son Software Libre cubren prácticamente todas las necesidades de los usuarios de computadoras, desde paquetes informáticos a herramientas de comunicación pasando por juegos y otras utilidades. 4.3.1. Información general sobre Software Libre ! Definición de Software Libre. URL:http:/www.gnu.org/philosophy/free-sw.es.html ! The Open Source Definition. URL:http://www.opensouce.org/docs/definition.php ! Por qué "Software Libre" es mejor que software de "Código Fuente Abierto": URL: http:// www.gnu.org/philosophy/free-software-for-freedom.es.html ! Categorías de Software Libre y no Libre: URL: http:// www.gnu.org/philosophy/categories.es.html ! Por qué el Software no debe tener propietarios: URL: http:// www.gnu.org/philosophy/why-free.es.html ! Software y Manuales Libres: URL: http:// www.gnu.org/philosophy/free-doc.es.html ! Vender Software Libre.: URL: http:// www.gnu.org/philosophy/selling.es.html 4.3.2. Herramientas de software / Software tools (Windows 98/XP y LINUX) Si se quiere tener acceso a algunas de las herramientas y saber a detalle de cuales son, visitar el URL: http://www.fisica.uson.mx/carlos/Software/ ! Navegadores de Internet (Web Browsers) ! Programas para Mensajes Instantáneos ! Programas para trabajo en redes ! Preparación de Documentos ! Editores GNU Emacs ! Software de aplicaciones científicas ! Software para Ingeniería ! Software para Estadística ! Manipulación de imágenes ! Multimedia ! Software de Otras aplicaciones o Programas para construir Mapas Mentales o Conceptuales o Compresión de archivos o Antivirus 65 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. Para todo esto se analizaron por su descripción y su compatibilidad con los cluster además de poder ser cuantificados de tal forma que se pudieran observar las ventajas, las categorías encontradas son las siguientes: Categoría: Aplicaciones científicas. ! Máxima: Implementación del sistema de cómputo simbólico Macsyma del MIT (Similar a Maple o Mathematica). ! Octave: Lenguaje de alto nivel para cómputo numérico (similar al Matlab). ! Scilab: Software científico para cómputo numérico. ! PLT Scheme (Dr. Scheme): lenguaje de programación Scheme. Categoría: Aplicaciones para Ingenieria. ! ! ! ! LeoCAD: construcción de objetos con bloques modulares, similar al Lego. gEDA: automatización de diseño electrónico. QCad: sistema CAD 2D. Dia: diseño de diagramas de flujo. Categoría: Manipulación de imágenes. ! Gimp: The GNU Image Manipulation Program (Manipulación de imágenes, similar a Photoshop) ! Blender: Gráficos 3D. ! POV-ray: Gráficos vectoriales en 3D. ! Sodipodi: Gráficos Vectoriales similar a Corel Draw ! Dia: Diagramas. Para efectos de pruebas se seleccionaron aplicaciones referentes al ámbito de los gráficos vectoriales, ya que son muy comunes en cualquier área del conocimiento, siempre se tiene la necesidad de mostrar imágenes, es por ello que entre las herramientas listadas se encuentra una aplicación llamada Pov-ray en la categoría de manipulación de imágenes y es precisamente con esta aplicación con la que se desarrollaron los ejemplos para ser analizados. Este programa manipulador de imágenes (Pov-ray,2005) tiene como misión la persistencia de visión, esto significa mostrar una reenderización continua y una alta calidad en las imágenes que se generan, el código se encuentra totalmente libre y disponible para aquellos que pretendan diseñar sus propias imágenes; esta disponible este software en sus versiones oficiales para Windows, Mac OS/Mac OS X y i86 Linux. POV-Ray tiene el equilibrio de poder y versatilidad para satisfacer a los usuarios sumamente experimentados y competentes, al mismo tiempo no está limitada a cautivar a nuevos usuarios. Por supuesto, el factor más importante es calidad de la imagen, y POV-Ray lo tiene. Los diseñadores al utilizar este software, se llega a tener la impresión de que se tratara de 66 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. una fotografía pero se trata de un concepto llamado la fotografía-realismo que es una habilidad avanzada. Trabajar con Pov-Ray para Linux, resulta interesante, ya que puede utilizar la consola que usa la biblioteca de SVGA; Pov-Ray para Unix no es un modelador, es decir no le permitirá diseñar en pantalla gráficamente a las escenas. Existen distintos shareware y el programa freeware disponible para este propósito. Para crear o modificar una imagen o escena simplemente se tendrá que revisar los archivos que contienen las órdenes y se tendrá que cambiar las instrucciones para tener un resultado distinto. Este procedimiento puede ser considerado primitivo, pero es muy básico para la creación de nuevas imágenes ya que proporciona flexibilidad. Para saber acerca de cómo se puede programar sus propias imágenes o modificar las existentes, la información puede ser obtenida desde el manual de usuarios que se proporciona desde el momento de la instalación del programa o en la página oficial del mismo (URL: http://www.povray.org/documentation/). Para obtener el programa se puede descargar desde el sitio oficial de la pagina en: URL: http://www.povray.org/download/, ya que se descompacta el programa que contiene la herramienta de Pov-Ray, los ejemplos quedan instalados en la ruta: /usr/local/share/povray-3.6/scenes/ En tal ruta se encontraran 14 carpetas (figura 4.5), clasificadas según su categoría, cada carpeta contendrá archivos con extensiones siguientes: Nom_arch.pov: este archivo es considerado el archivo principal. Nom_arch.ini: este archivo será utilizado por el Nom_arch.pov, cada vez que sea especificado en las instrucciones que el mismo usuario proporcione. La herramienta Pov-Ray cuando instala correctamente esta aplicación en las carpetas solo se encontraran por lo general estos dos tipos de archivos, los de extensión INI y POV, en su contenido, solo encontraremos código, un código similar a C, donde se contendrán las instrucciones a realizarse, el programa de Pov-Ray crea carpetas auxiliares como lo hace un lenguaje de programación tradicional, tales carpetas serán utilizadas para mandar llamar funciones o librerías ya existentes. Cuando en las carpetas generadas de Pov-Ray solo se encuentran archivos con extensión POV, esto indica que solamente se podrá generar un solo archivo tipo imagen (de forma estándar serán imágenes de tipo PNG) aun cuando el programa se reenderice n-veces. La forma para ejecutar los programas es la siguiente: Lo primero que se tiene que hacer es colocarse en la carpeta donde se encuentra el archivo a ejecutar (en este caso el de extensión POV). Ejemplo: cd /usr/local/share/povray-3.6/scenes/advance/ 67 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. [root@cluster03 advance]# Figura. 4.5. Carpetas instaladas. Para este caso, se parte de que debemos de tener permisos de súper usuario (root) y en el ejemplo el nombre del cluster03, responde al nombre del equipo que se utilizó. Posteriormente la instrucción básica es: [root@cluster03 advance]# povray Nom_arch.pov Con esta instrucción al momento de presionar enter empezara a proyectar la imagen y al término de esto, se mostrara un resumen del tiempo que se tardo en que la imagen se ejecutara. La imagen que se crea tendrá la extensión PNG. En caso de que el usuario requiera que la imagen sea procesada en extensión JPEG (JPG) la instrucción cambiara de la siguiente forma: [root@cluster03advance]#povray+iNom_arch.pov–fp+o-|cjpeg > Nom_arch.jpg De esta forma el proceso que se hará será el mismo, se mostrara la imagen en pantalla, pero con la única diferencia de que a su término el archivo imagen tendrá la extensión JPG. Otra forma para ejecutar estos archivos cambiara para cuando se tenga el mismo Nom_arch pero con ambas extensiones esto indicara que la imagen tendrá la característica de poderse reenderizar, es decir creara un conjunto de imágenes para que visualmente el usuario observe la rotación de la imagen, ejemplo: [root@cluster03 advance]# povray –iNom_arch.pov Nom_arch.ini [root@cluster03 advance]# povray Nom_arch.pov Nom_arch.ini. 68 ó 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. La opción de agregar el –i responde a una instrucción que reconoce el Pov-Ray que dice el anteponer el “-“ implicara que entrara información a un archivo para generar otro archivo tipo imagen, así como el “+” implicara que solo será salida de un archivo tipo imagen. 4.4. Estructura interna de un archivo tipo POV // Persistence Of Vision raytracer version 3.5 sample file. // By Chris Young 76702,1655 // Try changing C0 and C1 to various values from 0.0 to 1.0 in this scene. global_settings { assumed_gamma 2.2 } #include "colors.inc" Sección utilizada para la #declare C1=1; declaración de librerías a #declare C0=clock; llamar, así como también #declare Rad=1/6/10; definiciones de valores #declare Xval=-0.5; constantes. camera { location <0, 0, -150> direction <0, 0, 12> look_at <0, 0, 0> } light_source { <5000, 10000, -20000> color White} plane { z, Rad hollow on pigment {checker color rgb <1,.8,.8> color rgb <1,1,.8>} } #declare Font="cyrvetic.ttf" text{ ttf Font concat("C0 =",str(C0,1,3)),0.5, 0 Utilización de estilos de scale <1.25, 1.25, 4> fuentes existentes, así como translate <-2.75, 4, -30> utilización de funciones pigment { rgb <0.2, 0.8, 0.6> } existentes, indicando } coordenadas y colores a text{ ttf Font mostrar. concat("C1 =",str(C1,1,3)),0.5, 0 scale <1.25, 1.25, 4> translate <-2.75, 2.5, -30> pigment { rgb <0.2, 0.6, 0.8> } } union { #while (Xval <= 0.5) // This is the function that the "quilted" pattern uses #declare T=sqrt(3*Xval*Xval); #declare IT=1.0-T; #declare TQ=T*T*T+3*T*IT*IT*C0+3*T*T*IT*C1; sphere{<Xval,TQ,0>,Rad pigment{Red}} #declare Xval=Xval+0.01; #end scale 10 translate -5*y } 69 4. OPERATIVIDAD DE CLUSTER CON APLICACIONES DE INGENIERIA. 4.4.1. Estructura interna de un archivo tipo INI ; Persistence Of Vision raytracer version 3.5 sample file. Antialias=Off Antialias_Threshold=0.2 Antialias_Depth=3 Test_Abort_Count=100 Input_File_Name=plotqlt.pov Programa que le indica al archivo POV cual será la cantidad de archivos (png) que tendrá que crear y repetir (frame) y que en su conjunto permita observar que se esta reenderizando la imagen. Initial_Frame=1 Final_Frame=10 Initial_Clock=0 Final_Clock=1 Cyclic_Animation=on Pause_when_Done=off 1er. frame 2o. frame 3er. frame 4o. frame 5o. frame 6o. frame 7o. frame 8o. frame 9o. frame 10o. frame Figura. 4.6 Reenderización del archivo POV, a través del archivo INI Como se podrá observar la lectura de los archivos con extensión POV, tienen una estructura muy parecida a la de cualquier lenguaje de programación, por ejemplo lenguaje de programación “C” y el programa con extensión INI, tiene la característica de que contiene las llamadas al archivo POV así como indicar el número de frames que se deberán de generar, como se muestra en la figura 4.6 70 5. ANÁLISIS DE RESULTADOS. 5. ANÁLISIS DE RESULTADOS De un total de 351 ejemplos distribuidos en 13 categorías, solo se mostraran algunos ejemplos significativos de los cuales se distribuirán con ejemplos utilizando una computadora y utilizando el cluster diseñado con tres computadoras respectivamente. 5.1. Resultados obtenidos de una sola computadora A continuación se ilustraran algunos ejemplos ejecutados antes de usar el cluster con openMosix: 5.1.1. Categoría: advanced a). Nombre del archivo: abyss.pov Instrucción: [root@cluster03 advance]# povray –iabyss.pov Código: Ver Anexo 9. Imagen: a continuación se muestra la imagen generada (figura 5.1) Figura. 5.1. imagen generada por el archivo abyss.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 26 seconds Total Time: 0 hours 0 minutes 28 seconds 71 (2 seconds) (0 seconds) (26 seconds) (28 seconds) 5. ANÁLISIS DE RESULTADOS. b) Nombre del archivo: chess2.pov Instrucción: [root@cluster03 advance]# povray –ichess2.pov Código: Ver Anexo 10. Imagen: a continuación se muestra la imagen generada (figura 5.2) Figura. 5.2. imagen generada por el archivo chess2.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 57 seconds Total Time: 0 hours 0 minutes 57 seconds (0 seconds) (0 seconds) (57 seconds) (57 seconds) c) Nombre del archivo: grenadine.pov Instrucción: [root@cluster03 advance]# povray grenadine.pov Código: Ver Anexo 11. Imagen: a continuación se muestra la imagen generada (figura 5.3) 72 5. ANÁLISIS DE RESULTADOS. Figura. 5.3. imagen generada por el archivo grenadine.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds (0 seconds) Photon Time: 0 hours 0 minutes 47 seconds (47 seconds) Render Time: 0 hours 0 minutes 18 seconds (18 seconds) Total Time: 0 hours 1 minutes 5 seconds (65 seconds) d) Nombre del archivo: landscape.pov Instrucción: [root@cluster03 advance]# povray landscape.pov Código: Ver Anexo 12. Imagen: a continuación se muestra la imagen generada (figura 5.4) Figura. 5.4 imagen generada por el archivo landscape.pov 73 5. ANÁLISIS DE RESULTADOS. Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 34 seconds Total Time: 0 hours 0 minutes 36 seconds (2 seconds) (0 seconds) (34 seconds) (36 seconds) 5.1.2. Categoría: animation a) Nombre del archivo: camera2.pov, camera2.ini Instrucción: [root@cluster03 advance]# povray -icamera2.pov camera2.ini Código: Ver Anexo 13. Imagen: a continuación se muestran las imágenes generadas (figura 5.5) frame 1 frame 7 frame 13 frame 19 Frame 25 frame 2 frame 8 frame 14 frame 20 frame 26 frame 3 frame 4 frame 9 frame 10 frame 15 frame 16 frame 21 frame 22 frame 27 frame 28 frame 5 frame 11 frame 12 frame 17 frame 18 frame 23 frame 24 frame 29 frame 30 Figura. 5.5. imagen generada por el archivo camera2.pov 74 frame 6 5. ANÁLISIS DE RESULTADOS. Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 1 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 27 seconds Total Time: 0 hours 0 minutes 28 seconds (1 seconds) (0 seconds) (27 seconds) (28 seconds) b) Nombre del archivo: float4.pov Instrucción: [root@cluster03 advance]# povray -ifloat4.pov float.ini Código: Ver Anexo 14. Imagen: a continuación se muestran las imágenes generadas (figura 5.6) frame 1 frame 7 frame 2 frame 3 frame 8 frame 9 frame 13 frame 14 frame 15 frame 19 frame 20 frame 21 frame 25 frame 31 frame 26 frame 32 frame 4 frame 27 frame 33 frame 10 frame 16 frame 22 frame 28 frame 34 75 frame 5 frame 11 frame 17 frame 23 frame 29 frame 35 frame 6 frame 12 frame 18 frame 24 frame 30 frame 36 5. ANÁLISIS DE RESULTADOS. frame 37 frame 38 frame 43 frame 44 frame 49 frame 50 frame 39 frame 40 frame 45 frame 41 frame 46 frame 42 frame 47 frame 48 frame 51 Figura. 5.6. imagen generada por el archivo float4.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 44 seconds Total Time: 0 hours 0 minutes 48 seconds (4 seconds) (0 seconds) (44 seconds) (48 seconds) c) Nombre del archivo: vect1.pov Instrucción: [root@cluster03 advance]# povray -ivect1.pov vect1.ini Código: Ver Anexo 15. Imagen: a continuación se muestran las imágenes generadas (figura 5.7) frame 1 frame 7 frame 2 frame 8 frame 3 frame 9 frame 4 frame 10 76 frame 5 frame 11 frame 6 frame 12 5. ANÁLISIS DE RESULTADOS. frame 13 frame 14 frame 15 frame 16 frame 17 frame 18 frame 19 frame 20 frame 21 frame 22 frame 23 frame 24 frame 25 frame 31 frame 37 frame 43 frame 49 frame 55 frame 26 frame 32 frame 38 frame 44 frame 50 frame 56 frame 27 frame 28 frame 33 frame 34 frame 39 frame 40 frame 45 frame 52 frame 58 frame 30 frame 35 frame 41 frame 46 frame 51 frame 57 frame 29 frame 36 frame 42 frame 47 frame 53 frame 48 frame 54 frame 59 Figura. 5.7. imagen generada por el archivo vect1.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 16 seconds Total Time: 0 hours 1 minutes 16 seconds 77 (0 seconds) (0 seconds) (76 seconds) (76 seconds) 5. ANÁLISIS DE RESULTADOS. d) Nombre del archivo: vect2.pov Instrucción: [root@cluster03 advance]# povray -ivect2.pov vect2.ini Código: Ver Anexo 16. Imagen: a continuación se muestran las imágenes generadas (figura 5.8) frame 1 frame 2 frame 3 frame 4 frame 7 frame 8 frame 9 frame 10 frame 13 frame 14 frame 15 frame 19 frame 25 frame 31 frame 37 frame 43 frame 20 frame 26 frame 32 frame 38 frame 44 frame 16 frame 21 frame 27 frame 33 frame 22 frame 28 frame 34 frame 39 frame 45 frame 40 frame 46 78 frame 5 frame 11 frame 17 frame 23 frame 29 frame 35 frame 41 frame 47 frame 6 frame 12 frame 18 frame 24 frame 30 frame 36 frame 42 frame 48 5. ANÁLISIS DE RESULTADOS. frame 49 frame 55 frame 50 frame 56 frame 51 frame 57 frame 52 frame 58 frame 53 frame 59 frame 54 frame 60 Figura. 5.8. imagen generada por el archivo vect2.pov Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 39 seconds Total Time: 0 hours 1 minutes 41 seconds (2 seconds) (0 seconds) (99 seconds) (101 seconds) En la tabla 5.1 se anexan algunos resultados obtenidos de algunas categorías Tabla 5.1. Resultados con una sola computadora Categoría Advanced Nom_arch Resultados con una sola computadora desk.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) diffract.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) float5.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 1 2 seconds seconds seconds seconds (1 (0 (1 (2 seconds) seconds) seconds) seconds) gaussianblob.pov Total Scene Processing Times Parse Time: 0 hours 1 minutes 46 seconds (106 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 24 seconds (24 seconds) Total Time: 0 hours 2 minutes 10 seconds (130 seconds) infinitybox.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes isocacti.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 3 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 19 seconds Total Time: 0 hours 0 minutes 22 seconds 79 0 0 3 3 seconds seconds seconds seconds (0 (0 (3 (3 seconds) seconds) seconds) seconds) (3 seconds) (0 seconds) (19 seconds) (22 seconds) 5. ANÁLISIS DE RESULTADOS. lamppost.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes mediasky.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 2 minutes 26 seconds Total Time: 0 hours 2 minutes 26 seconds (0 seconds) (0 seconds) (146 seconds) (146 seconds) raddem.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 31 seconds Total Time: 0 hours 1 minutes 35 seconds (4 seconds) (0 seconds) (91 seconds) (95 seconds) ambient.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes (1 (0 (0 (1 diffuse.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 13 seconds Total Time: 0 hours 0 minutes 15 seconds (2 seconds) (0 seconds) (13 seconds) (15 seconds) float1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 3 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 53 seconds Total Time: 0 hours 0 minutes 56 seconds (3 seconds) (0 seconds) (53 seconds) (56 seconds) i_o.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 4 minutes Total Time: 0 hours 4 minutes (2 seconds) (0 seconds) (243 seconds) (245 seconds) Camera micro.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 24 seconds Total Time: 0 hours 1 minutes 24 seconds Language trace2.pov Animations tracevines.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 7 7 1 0 0 1 2 0 3 5 0 0 4 4 seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds seconds (0 (0 (7 (7 seconds) seconds) seconds) seconds) seconds) seconds) seconds) seconds) (0 seconds) (0 seconds) (84 seconds) (84 seconds) (0 (0 (4 (4 seconds) seconds) seconds) seconds) Total Scene Processing Times Parse Time: 0 hours 0 minutes 26 seconds (26 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 7 seconds (7 seconds) Total Time: 0 hours 0 minutes 33 seconds (33 seconds) trace-wicker.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 3 4 seconds seconds seconds seconds (1 (0 (3 (4 seconds) seconds) seconds) seconds) vturbulence.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 5 5 seconds seconds seconds seconds (0 (0 (5 (5 seconds) seconds) seconds) seconds) 80 5. ANÁLISIS DE RESULTADOS. Light Objectsmods arrays1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) arealit1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) arealit2.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) arealit3.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 7 8 seconds seconds seconds seconds (1 (0 (7 (8 seconds) seconds) seconds) seconds) fillite.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 0 0 seconds seconds seconds seconds (0 (0 (0 (0 seconds) seconds) seconds) seconds) Laser.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) parallel_lights.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) double_ illuminate.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 1 2 seconds seconds seconds seconds (1 (0 (1 (2 seconds) seconds) seconds) seconds) no_image.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) no_reflection.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) 5.2. Resultados obtenidos utilizando el cluster Los resultados que se mostraran corresponden cuando ya se tienen las tres computadoras aplicándole openmosix y tratando de observar como migran los procesos o se logra compartir la memoria. 81 5. ANÁLISIS DE RESULTADOS. 5.2.1 Categoría: advanced a) Nombre del archivo: abyss.pov Imagen: a continuación se muestra la imagen generada (figura 5.9) Figura. 5.9. imagen generada por el archivo abyss.pov Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.10 (a),(b),(c)) Figura. 5.10. (a) nodos que reciben migración en el cluster 82 5. ANÁLISIS DE RESULTADOS. Figura. 5.10. (b) uso de la memoria solicitada en los otros equipos. Figura. 5.10. (c) nodos activos, migraciones en proceso. Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 27 seconds Total Time: 0 hours 0 minutes 29 seconds (2 seconds) (0 seconds) (27 seconds) (29 seconds) b) Nombre del archivo: chess2.pov Imagen: a continuación se muestra la imagen generada (figura 5.11) 83 5. ANÁLISIS DE RESULTADOS. Figura. 5.11. imagen generada por el archivo chess2.pov Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.12 (a),(b),(c),(d)) Figura. 5.12. (a) y (b) nodos que reciben migración en el cluster Figura. 5.12. (c) nodos activos, migraciones en proceso 84 5. ANÁLISIS DE RESULTADOS. Figura. 5.12. (d) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 1 minutes Total Time: 0 hours 1 minutes 0 0 6 6 seconds seconds seconds seconds (0 seconds) (0 seconds) (66 seconds) (66 seconds) c) Nombre del archivo: grenadine.pov Imagen: a continuación se muestra la imagen generada (figura 5.13) Figura. 5.13. imagen generada por el archivo grenadine.pov Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.14 (a),(b),(c)) 85 5. ANÁLISIS DE RESULTADOS. Figura. 5.14. (a) nodos que reciben migración en el cluster Figura. 5.14. (b) uso de la memoria solicitada en los otros equipos Figura. 5.14. (c) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds (0 seconds) Photon Time: 0 hours 0 minutes 52 seconds (52 seconds) Render Time: 0 hours 0 minutes 30 seconds (30 seconds) Total Time: 0 hours 1 minutes 22 seconds (82 seconds) 86 5. ANÁLISIS DE RESULTADOS. d) Nombre del archivo: landscape.pov Imagen: a continuación se muestra la imagen generada (figura 5.15) Figura. 5.15. imagen generada por el archivo landscape.pov Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.16 (a),(b),(c),(d),(e)) Figura. 5.16. (a) y (b) nodos que reciben migración en el cluster Figura. 5.16. (c) uso de la memoria solicitada en los otros equipos 87 5. ANÁLISIS DE RESULTADOS. Figura. 5.16. (d) uso de la memoria solicitada en los otros equipos Figura. 5.16. (e) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 58 seconds Total Time: 0 hours 1 minutes 0 seconds (2 seconds) (0 seconds) (58 seconds) (60 seconds) 5.2.2. Categoría: animation a) Nombre del archivo: camera2.pov, camera2.ini Imagen: Las imágenes correspondientes se encuentran referenciadas en la sección 5.2.1 figura 5.5 Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.17 (a),(b),(c),(d),(e),(f)) 88 5. ANÁLISIS DE RESULTADOS. Figura. 5.17. (a),(b) y (c) nodos que reciben migración en el cluster Figura. 5.17. (d) uso de la memoria solicitada en los otros equipos 89 5. ANÁLISIS DE RESULTADOS. Figura. 5.17. (e) uso de la memoria solicitada en los otros equipos Figura. 5.17. (f) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 1 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 30 seconds Total Time: 0 hours 0 minutes 31 seconds (1 seconds) (0 seconds) (30 seconds) (31 seconds) b) Nombre del archivo: float4.pov Imagen: Las imágenes correspondientes se encuentran referenciadas en la sección 5.2.1 figura 5.6 Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.18 (a),(b),(c)) 90 5. ANÁLISIS DE RESULTADOS. Figura. 5.18. (a) nodos que reciben migración en el cluster Figura. 5.18. (b) uso de la memoria solicitada en los otros equipos Figura. 5.18. (c) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 50 seconds Total Time: 0 hours 0 minutes 54 seconds 91 (4 seconds) (0 seconds) (50 seconds) (54 seconds) 5. ANÁLISIS DE RESULTADOS. c) Nombre del archivo: vect1.pov Imagen: Las imágenes correspondientes se encuentran referenciadas en la sección 5.2.1 figura 5.7. Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.19 (a),(b),(c),(d),(e),(f)) Figura. 5.19. (a), (b) y (c) nodos que reciben migración en el cluster Figura. 5.19. (d) uso de la memoria solicitada en los otros equipos 92 5. ANÁLISIS DE RESULTADOS. Figura. 5.19. (e) uso de la memoria solicitada en los otros equipos Figura. 5.19. (f) uso de la memoria solicitada en los otros equipos Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 36 seconds Total Time: 0 hours 1 minutes 36 seconds (0 seconds) (0 seconds) (96 seconds) (96 seconds) d) Nombre del archivo: vect2.pov Imagen: Las imágenes correspondientes se encuentran referenciadas en la sección 5.2.1 figura 5.8 Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.20 (a),(b),(c),(d),(e),(f)) 93 5. ANÁLISIS DE RESULTADOS. Figura. 5.20. (a), (b) nodos que reciben migración en el cluster Figura. 5.20. (c) uso de la memoria solicitada en los otros equipos Figura. 5.20 (d) uso de la memoria solicitada en los otros equipos 94 5. ANÁLISIS DE RESULTADOS. Resultados Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 59 seconds Total Time: 0 hours 2 minutes 1 seconds (2 seconds) (0 seconds) (119 seconds) (121 seconds) En la tabla 5.2 se anexan algunos resultados obtenidos de algunas categorías Tabla 5.2. Resultados usando cluster Categoría Advanced animations Nom_arch Resultados usando cluster (con 3 maquinas) desk.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) diffract.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) float5.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 2 3 seconds seconds seconds seconds (1 (0 (2 (3 seconds) seconds) seconds) seconds) gaussianblob.pov Total Scene Processing Times Parse Time: 0 hours 1 minutes 46 seconds (106 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 44 seconds (44 seconds) Total Time: 0 hours 2 minutes 30 seconds (150 seconds) infinitybox.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes isocacti.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 3 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 25 seconds Total Time: 0 hours 0 minutes 28 seconds (3 seconds) (0 seconds) (25 seconds) (28 seconds) lamppost.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes (0 (0 (9 (9 mediasky.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 5 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 2 minutes 26 seconds Total Time: 0 hours 2 minutes 31 seconds (5 seconds) (0 seconds) (146 seconds) (151 seconds) raddem.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 39 seconds Total Time: 0 hours 1 minutes 43 seconds (4 seconds) (0 seconds) (99 seconds) (103 seconds) ambient.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 95 0 0 4 3 0 0 9 9 seconds seconds seconds seconds seconds seconds seconds seconds (0 (0 (4 (3 seconds) seconds) seconds) seconds) seconds) seconds) seconds) seconds) 1 seconds (1 seconds) 5. ANÁLISIS DE RESULTADOS. Photon Time: Render Time: Total Time: 0 hours 0 hours 0 hours 0 minutes 0 minutes 0 minutes 0 seconds (0 seconds) 0 seconds (0 seconds) 1 seconds (1 seconds) diffuse.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 15 seconds Total Time: 0 hours 0 minutes 17 seconds (2 seconds) (0 seconds) (15 seconds) (17 seconds) float1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 3 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 56 seconds Total Time: 0 hours 0 minutes 59 seconds (3 seconds) (0 seconds) (56 seconds) (59 seconds) i_o.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 4 minutes 13 seconds Total Time: 0 hours 4 minutes 15 seconds (2 seconds) (0 seconds) (253 seconds) (253 seconds) Camera micro.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 0 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 30 seconds Total Time: 0 hours 1 minutes 30 seconds (0 seconds) (0 seconds) (90 seconds) (90 seconds) Language trace2.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes (0 (0 (5 (5 tracevines.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 26 seconds (26 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 17 seconds (17 seconds) Total Time: 0 hours 0 minutes 43 seconds (43 seconds) trace-wicker.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 4 5 seconds seconds seconds seconds (1 (0 (4 (5 seconds) seconds) seconds) seconds) vturbulence.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 5 5 seconds seconds seconds seconds (0 (0 (5 (5 seconds) seconds) seconds) seconds) arrays1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) arealit1.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes 1 seconds (1 seconds) 0 seconds (0 seconds) Light arealit2.pov arealit3.pov 96 0 0 5 5 seconds seconds seconds seconds seconds) seconds) seconds) seconds) 5. ANÁLISIS DE RESULTADOS. Render Time: Total Time: objectsmods 0 hours 0 hours 0 minutes 0 minutes 8 seconds (8 seconds) 9 seconds (9 seconds) fillite.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 0 0 seconds seconds seconds seconds (0 (0 (0 (0 seconds) seconds) seconds) seconds) Laser.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) parallel_lights.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) double_ illuminate.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 1 2 seconds seconds seconds seconds (1 (0 (1 (2 seconds) seconds) seconds) seconds) no_image.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 1 1 seconds seconds seconds seconds (0 (0 (1 (1 seconds) seconds) seconds) seconds) no_reflection.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 2 2 seconds seconds seconds seconds (0 (0 (2 (2 seconds) seconds) seconds) seconds) 5.3. Ejecución múltiple usando cluster 5.3.1. Categoría: Advanced a) Nombre de los archivos: a. abyss.pov, b. benchmark.pov, c. biscuit.pov, d. bwstripe.pov, e. chess2.pov, f. desk.pov, g. diffract.pov, h. float5.pov Instrucción: en la figura 5.21 se muestra la instrucción para su ejecución. Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.22 (a),(b),(c),(d),(e),(f),(g)) 97 5. ANÁLISIS DE RESULTADOS. Figura. 5.21. Instrucciones a ejecutarse Figura. 5.22. (a), (b), (c), (d) nodos que reciben migración en el cluster 98 5. ANÁLISIS DE RESULTADOS. Figura. 5.22. (e) uso de la memoria solicitada en los otros equipos Figura. 5.22. (f) uso de la memoria solicitada en los otros equipos Figura. 5.22. (g) uso de la memoria solicitada en los otros equipos Resultados abyss.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 1 minutes Total Time: 0 hours 1 minutes 5 0 4 9 seconds seconds seconds seconds (5 seconds) (0 seconds) (64 seconds) (69 seconds) benchmark.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes 99 0 seconds (0 seconds) 0 seconds (0 seconds) 5. ANÁLISIS DE RESULTADOS. Render Time: Total Time: 0 hours 0 hours 0 minutes 0 minutes 0 seconds (0 seconds) 0 seconds (0 seconds) biscuit.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 0 0 0 0 seconds seconds seconds seconds (0 (0 (0 (0 seconds) seconds) seconds) seconds) 0 0 3 3 seconds seconds seconds seconds (0 (0 (3 (3 seconds) seconds) seconds) seconds) bwstripe.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes chess2.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 1 minutes 41 seconds Total Time: 0 hours 1 minutes 45 seconds (4 seconds) (0 seconds) (101 seconds) (105 seconds) desk.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes 6 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 0 minutes 46 seconds Total Time: 0 hours 0 minutes 52 seconds (6 seconds) (0 seconds) (46 seconds) (52 seconds) diffract.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes 1 0 3 4 seconds seconds seconds seconds (1 (0 (3 (4 seconds) seconds) seconds) seconds) 1 0 6 7 seconds seconds seconds seconds (1 (0 (6 (7 seconds) seconds) seconds) seconds) float5.pov Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 0 minutes Total Time: 0 hours 0 minutes En la figura 5.23 inciso (a) se muestra la cantidad de memoria mínima, media y/o máxima utilizada en el nodo 50 para la ejecución de aplicaciones que se encuentran en el nodo que esta ejecutando la aplicación; en el inciso (b) y (c) se observa la cantidad de recursos de memoria que se utilizo por petición de la herramienta de openMosix, la 100 5. ANÁLISIS DE RESULTADOS. cual se encargo de migrar los procesos que eran posible migrarse y los que no fueron posible su migración, se utilizo la memoria compartida desde el nodo 51 y 52. Figura. 5.23. (a) grafica mostrando el resumen de recursos utilizado en el nodo 50 Figura. 5.23. (b) grafica mostrando el resumen de recursos utilizado en el nodo 51 Figura. 5.23. (c) grafica mostrando el resumen de recursos utilizado en el nodo 52 En la figura 5.23 inciso (d) se muestra de forma grafica los niveles correspondientes a los tres nodos (50,51 y 52). 101 5. ANÁLISIS DE RESULTADOS. Figura. 5.23 (d) grafica mostrando el resumen de recursos utilizado en los nodo 50, 51 y 52 5.3.2. Categoría: animation b) Nombre de los archivos: a. ambient.pov, ambient.ini, b. boing1.pov, boing1.ini, c. bounce.pov, bounce.ini, d. glsbng.pov, glsbng.ini, e. camera2.pov, camera2.ini, f. float1.pov, float1.ini, g. float2.pov, float2.ini y h. float3.pov, float3.ini Instrucción: en la figura 5.24 se muestra la instrucción para su ejecución. Figura. 5.24. Instrucciones a ejecutarse 102 5. ANÁLISIS DE RESULTADOS. Imágenes OpenMosixView: a continuación se muestran las imágenes producidas donde se observan las migraciones de procesos y memoria. (ver figura 5.25 (a),!,(p)) Figura. 5.25. (a), (b) nodos que reciben migración en el cluster Figura. 5.25. (c), (d) nodos que reciben migración en el cluster Figura. 5.25. (e), (f) nodos que reciben migración en el cluster 103 5. ANÁLISIS DE RESULTADOS. Figura. 5.25. (g), (h) nodos que reciben migración en el cluster Figura. 5.25. (i) uso de la memoria solicitada en los otros equipos Figura. 5.25. (j) uso de la memoria solicitada en los otros equipos Figura. 5.25. (k) uso de la memoria solicitada en los otros equipos 104 5. ANÁLISIS DE RESULTADOS. Figura. 5.25. (l) uso de la memoria solicitada en los otros equipos Figura. 5.25. (m) uso de la memoria solicitada en los otros equipos Figura. 5.25. (n) uso de la memoria solicitada en los otros equipos Figura. 5.25. (o) uso de la memoria solicitada en los otros equipos 105 5. ANÁLISIS DE RESULTADOS. Figura. 5.25. (p) uso de la memoria solicitada en los otros equipos Resultados ambient.pov, ambient.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 2 minutes 27 seconds Total Time: 0 hours 2 minutes 31 seconds (4 seconds) (0 seconds) (147 seconds) (151 seconds) boing1.pov, boing1.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 8 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 4 minutes 43 seconds Total Time: 0 hours 4 minutes 51 seconds (8 seconds) (0 seconds) (283 seconds) (291 seconds) bounce.pov, bounce.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 7 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 11 minutes 15 seconds Total Time: 0 hours 11 minutes 22 seconds (7 seconds) (0 seconds) (675 seconds) (682 seconds) glsbng.pov, glsbng.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 8 minutes 10 seconds Total Time: 0 hours 8 minutes 14 seconds (4 seconds) (0 seconds) (490 seconds) (494 seconds) camera2.pov, camera2.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes Photon Time: 0 hours 0 minutes Render Time: 0 hours 4 minutes Total Time: 0 hours 4 minutes 106 3 0 4 7 seconds seconds seconds seconds (3 seconds) (0 seconds) (244 seconds) (247 seconds) 5. ANÁLISIS DE RESULTADOS. float1.pov, float1.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 4 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 5 minutes 43 seconds Total Time: 0 hours 5 minutes 47 seconds (4 seconds) (0 seconds) (343 seconds) (347 seconds) float2.pov, float2.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 14 seconds (14 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 5 minutes 8 seconds (308 seconds) Total Time: 0 hours 5 minutes 22 seconds (322 seconds) float3.pov, float3.ini Total Scene Processing Times Parse Time: 0 hours 0 minutes 8 seconds Photon Time: 0 hours 0 minutes 0 seconds Render Time: 0 hours 5 minutes 25 seconds Total Time: 0 hours 5 minutes 33 seconds (8 seconds) (0 seconds) (325 seconds) (333 seconds) En la figura 5.26 inciso (a) se muestra la cantidad de memoria mínima, media y/o máxima utilizada en el nodo 50 para la ejecución de aplicaciones que se encuentran en el nodo que esta ejecutando la aplicación; en el inciso (b) y (c) se observa la cantidad de recursos de memoria que se utilizo por petición de la herramienta de openMosix, la cual se encargo de migrar los procesos que eran posible migrarse y los que no fueron posible su migración, se utilizo la memoria compartida desde el nodo 51 y 52. Figura. 5.26. (a) grafica mostrando el resumen de recursos utilizado en el nodo 50 Figura. 5.26. (b) grafica mostrando el resumen de recursos utilizado en el nodo 51 107 5. ANÁLISIS DE RESULTADOS. Figura. 5.26. (c) grafica mostrando el resumen de recursos utilizado en el nodo 52 Figura. 5.26. (d) grafica mostrando el resumen de recursos utilizado en los nodo 50, 51 y 52 5.4. Análisis de resultados De las 13 categorías que contenían un total de 351 archivos, se plasmaron en este capitulo solo algunos de los más significativos, donde se puede deducir lo siguiente: 5.4.1. Ejecución sin utilización del cluster Al momento de ejecutar el archivo que renderiza y que crea la imagen en formato PNG ó JPG según fuera el caso, lo observado era que el excesivo uso de memoria que se solicitaba a la maquina ocasionaba que la Terminal de trabajo en la que se encontraba generándose la imagen se consumieran los recursos principalmente de memoria; teniendo con ello que no se pudieran trabajar otras aplicaciones en ese momento. La manipulación de procesos del archivo que se estaba ejecutando, hacían que el procesador atendiera toda la petición de la aplicación de tal forma que en algún fragmento de segundos las peticiones sobre otras acciones a realizar las mandara al buffer puesto que las operaciones matemáticas que realizaba para producir el grafico absorbía los recursos de la Unidad Aritmética Lógica. Posteriormente se volvieron a ejecutar los mismo ejercicios y se obtuvieron sus resultados de forma parcial, donde se observo que la aplicación de openMosix empezó a ejecutarse de tal manera que delego funciones especificas a las dos maquinas con las que se apoyo, esa delegación de funciones principalmente fue de solicitar recursos de memoria para que la maquina que estaba ejecutando el programa quedara disponible 108 5. ANÁLISIS DE RESULTADOS. para otra u otras aplicaciones teniendo como resultados que en ningún momento se perdiera el control. Lo que se observo fue que las dos tablas de resultados obtenidos en distintos eventos, generaron resultados diferentes, como se observan a continuación en la tabla 5.3 y 5.4 Tabla. 5.3. Resultados obtenidos de una sola computadora Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds (2 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 26 seconds (26 seconds) Total Time: 0 hours 0 minutes 28 seconds (28 seconds) Tabla. 5.4. Resultados obtenidos usando el cluster Total Scene Processing Times Parse Time: 0 hours 0 minutes 2 seconds (2 seconds) Photon Time: 0 hours 0 minutes 0 seconds (0 seconds) Render Time: 0 hours 0 minutes 27 seconds (27 seconds) Total Time: 0 hours 0 minutes 29 seconds (29 seconds) Como se podrá observar, cuando no se aplicó el cluster el tiempo de ejecución fue menor que cuando si se aplicó, pero si consideramos el comentario anterior con respecto a la libertad que tuvo el procesador para poder atender mas peticiones y no ser consumida solamente por esta ejecución; la ventaja de usar openMosix (es decir usar cluster) radica en que al detectar nodos dentro de la red que se encuentren desahogados u ociosos (que no estén ejecutando ninguna aplicación) permite que el equipo que presente sobrecarga de trabajo pueda solicitarles a los demás nodos recursos de memoria o si es necesario de procesamiento. 5.4.2. Ejecución utilizando el cluster Como se podrán observar en los ejemplos descritos en los subtemas anteriores, cuando se empezaron a migrar los procesos y a solicitar memoria a los diferentes nodos, el tiempo de ejecución subió y en algunos casos por un 20%, esto se debe a los tiempos que espero el nodo raíz (el que ejecuto el programa) en recibir las respuestas de los procesos enviados a los distintos nodos y de la solicitud de memoria que les hizo a los mismos nodos; este tiempo no debe de preocupar por que en ningún momento ocasiono que cualquiera de los nodos conectados en el cluster se saturaran e impidieran que alguna otra aplicación se pudiera ejecutar. Se seleccionaron de forma aleatoria 8 ejemplos de la categoría advanced y animations, la prueba que se realizo consistía en ejecutar los ejercicios de forma casi simultanea y observar como el cluster se comportaba, logrando como resultados las graficas que muestran que en su momento la memoria que se necesito para que se ejecutaran los ejemplos de tal forma que no se saturara el buffer y poder seguir utilizando los nodos para realizar otras actividades fue todo un éxito, ya que se observo como openMosix administro los ejemplos y solicito la memoria así como migro algunas tareas a los nodos vecinos teniendo como resultado un procesamiento ligero y permitiendo en este caso poder navegar en Internet, realizar alguna búsqueda y hasta ejecutar tareas sencillas 109 5. ANÁLISIS DE RESULTADOS. como lectura de archivos de texto y en ningún momento los equipos se sintieron mermados en su desempeño. Posteriormente se realizo la prueba que de forma manual se migraran algunos procesos a distintos nodos para observar que sucedía cuando los procesos se forzaban a ser migrados; observando que los resultados no eran satisfactorios en su totalidad ya que en algunos casos los ejemplos no contenían procesos que fueran fáciles de separar por su forma no estructurada; pero aun así openMosix atendía la petición que como usuario se le daba y el inconveniente era que los tiempos se ampliaban hasta en un 25%. Con esta acción se considera que para trabajar con openMosix es mejor dejar que la misma herramienta trate de migrar los procesos de ser posible o de lo contrario dejar que solicite la cantidad de memoria RAM con la que cuente disponible los nodos vecinos; ya que esta ultima parte resulta muy dinámica y eficiente para la herramienta de openMosix. Las pruebas que se hicieron se considero que dentro de la red interna que se utilizo solamente existiera el flujo de comunicación entre los nodos para uso exclusivo de las aplicaciones que se estaban ejecutando; queriendo decir que se realizaron pruebas sin utilizar la red para alguna otra aplicación que no fuera la herramienta de pov-ray, teniendo resultados importantes ya que al estar la red exclusivamente para uso de la migración de procesos y solicitudes de memoria hacia los nodos, la eficiencia sube considerablemente; ya que no se tiene en ningún momento saturación a la red por algunos otros factores que pudieran entorpecer el trabajo. Se llego a esta conclusión con respecto a la red, ya que también se probaron los ejemplos de tal forma que se saturara lo mas posible haciendo acciones como la de enviar archivos de trabajo por mas de 1 GB de un nodo a otro, también solicitando búsquedas desde navegadores de Internet y haciendo descargas de archivos de trabajo mayores a los 10 MB; los resultados que nos produjeron fueron: que sin activar la herramienta de openMosix, los tiempos son consideradamente elevados hasta en un 40%; pero cuando activamos la herramienta para que el cluster funcione se esta ahorrando ese mismo porcentaje. 110 ANEXO 1. Glosario de Términos ANEXO 1. Glosario de Términos Cluster: Un conjunto de computadoras independientes interconectadas, usadas como un recurso unificado de cómputo. Clustering: Implica proveer niveles de disponibilidad y escalabilidad de un sistema al menor costo. Tipos de Clusters Beowulf: Es un cluster de componentes commodity de cómputo dedicado a un problema paralelo. El primer Cluster de este tipo fue desarrollado por Thomas Sterling, de la división de Ciencias de la Tierra de la NASA en JPL California, esta solución popular ha sido ampliamente aceptada en varios ambientes de producción, principalmente laboratorios de investigación y sitios académicos. En un Beowulf los nodos se conectan por medio de una red privada y sólo el "nodo maestro" es visible desde el exterior. El nodo maestro está reservado para accesar, compilar y manejar las aplicaciones a ejecutar. Definiciones básicas Rendimiento: Es la efectividad del desempeño de una computadora, sobre una aplicación o un benchmark en particular. En las mediciones de rendimiento están involucrados velocidad, costo y eficiencia. Flops: Es una medida de la velocidad del procesamiento numérico del procesador. Son operaciones de punto flotante por segundo. Se utilizan en unidades de millones de flops: MegaFlops; y en Miles de Millones de flops: GigaFlops. Alto Rendimiento (HPC): Gran demanda de procesamiento de datos en procesadores, memoria y otros recursos de hardware, donde la comunicación entre ellos es muy rápida. Nodo: Se refiere a una computadora sola, que contiene recursos específicos, tales como memoria, interfaces de red, uno o más CPU, etc. Métodos Numéricos: Son técnicas mediante las cuales es posible formular problemas que se pueden resolver usando operaciones aritméticas y que finalmente son resueltos usando una computadora. Problemas de Gran Reto: Son problemas fundamentales de la Ciencia e Ingeniería, cuyas soluciones pueden ser desarrolladas aplicando técnicas del Cómputo de Alto Rendimiento. 111 ANEXO 1. Glosario de Términos Escalabilidad: Generalmente se mide la eficiencia de un problema, utilizando un tamaño y un número de procesadores fijo, lo cual es insuficiente, pues los resultados serán diferentes cuando aumentamos o disminuimos el tamaño del problema y el número de procesadores. Es decir, existe un problema de escalabilidad. Cuando se aumenta el número de procesadores para el mismo tamaño del problema, la sobrecarga debido al paralelismo (comunicaciones, desbalanceo de carga) aumenta. Similarmente, podemos tener casos en donde el tamaño del problema es muy pequeño para tener una evaluación real del problema sobre cierta máquina. Cómputo Paralelo Computadora Paralela: Máquina con dos o más procesadores que pueden trabajar simultánea y/o coordinadamente. Son de dos tipos: MIMD (cada procesador puede ejecutar diferentes instrucciones sobre diferentes datos) y SIMD (los procesadores ejecutan las mismas instrucciones pero con diferentes datos). Actualmente las computadoras paralelas se han dividido en diversos tipos, destacando aquellas del tipo CC-NUMA con memoria distribuida compartida. NUMA (Non Módulos de procesador y memoria están integrados Uniform Memory conjuntamente, de tal manera que es más rápido acceder a la Access): memoria local (del mismo módulo) que a alguna otra memoria remota (en otro módulo). Coherencia de Cache: Cuando copias del mismo bloque de memoria están presentes en los caches de varios procesadores, si un procesador actualiza un valor en una variable que se encuentra en ese bloque, los otros procesadores continuarán accediendo a datos viejos que están en su copia del bloque de memoria que está en sus caches. A menos que se realice una acción especial que mantenga la coherencia de datos entre los caches usando algún tipo de hardware específico tal como la memoria de directorio. Memoria Compartida: En una máquina paralela existe una sola memoria que puede ser accesada por todos los procesadores. Memoria Distribuida: Cada uno de los procesadores de un multiprocesador tiene asociado a él una unidad de memoria. Computadora Vectorial: Posee un conjunto de unidades funcionales utilizadas para procesar vectores eficientemente. Contiene registros vectoriales para operar sobre ellos en un solo ciclo de reloj. 112 ANEXO 1. Glosario de Términos SMP: Procesadores Procesador RISC (Reduced Instruction Set Computer): Compiladores Compiladores y Paralelización Automática: Arquitectura informática en la que varios procesadores comparten la misma memoria, que contiene una copia del sistema operativo, una copia de todas las aplicaciones que están en uso y una copia de los datos. Como el sistema operativo divide la carga de trabajo en tareas y asigna esas tareas a los procesadores que estén disponibles, SMP reduce el tiempo de las transacciones. Componentes de los Clusters Caracterizado por un conjunto pequeño de instrucciones simples, y con ejecución encadenada de ellas (pipelined). El desarrollo de compiladores que pueden paralelizar automáticamente ha ido evolucionando durante más de una década, con desarrollos significativos en el análisis de dependencia de accesos de datos. Los compiladores son ahora capaces de paralelizar automáticamente programas en FORTRAN basados en manejo de arreglos y tener un rendimiento considerable en multiprocesadores de pequeña escala. Se han logrado también avances en los algoritmos de los compiladores para manejar la localidad de datos en los caches y en la memoria principal, en optimizar la orquestación de la comunicación basándose en las características de desempeño de una arquitectura. Sin embargo, los compiladores no son todavía capaces de paralelizar eficientemente programas más complejos, especialmente aquellos que hacen un uso substancial de apuntadores, pues la dirección que guarda un apuntador no se conoce durante la fase de compilación. Lenguajes de Programación Paralela MPI:Message Passing Interface. Biblioteca estándar para programación paralela en el modelo de intercambio de mensajes. En este estándar se han incluido los aspectos más relevantes de otras bibliotecas de programación paralela, como NX 2, P4 entre otras. Entre las ventajas de MPI se encuentra la disponibilidad de varios modos de comunicación, los cuales permiten al programador el uso de buffers para el envío rápido de mensajes cortos, la sincronización de procesos o el traslape de procesos de cómputo con procesos de comunicación. Esto último reduce el tiempo de ejecución de un programa paralelo, pero tiene la desventaja de que el programador debe ser más cuidadoso para evitar la corrupción de mensajes. Dos de las principales distribuciones de MPI son: LAM/MPI y MPICH. PVM: Parallel Virtual Machine. Creado en el verano de 1989 por el Oak Ridge National Laboratory y desarrollado, posteriormente, junto con la 113 ANEXO 1. Glosario de Términos Universidad de Tennessee en los EUA. PVM es una biblioteca de envío de mensajes, totalmente libre, capaz de trabajar en redes homogéneas y heterogéneas, que hace uso de los recursos existentes en algún centro de trabajo para poder construir una máquina paralela de bajo costo, obteniendo su mejor rendimiento en "horas muertas". PVM maneja transparentemente el ruteo de todos los mensajes, conversión de datos y calendarización de tareas a través de una red de arquitecturas incompatibles. PVM está diseñado para conjuntar recursos de cómputo y proveer a los usuarios de una plataforma paralela para correr sus aplicaciones, independientemente de él número de computadoras distintas que utilicen y dónde se encuentren localizadas. El modelo computacional de PVM es simple y además muy general. El usuario escribe su aplicación como una colección de tareas cooperativas. Las tareas accesan los recursos de PVM a través de una biblioteca de rutinas. Estas rutinas permiten la inicialización y terminación de tareas a través de la red, así como la comunicación y sincronización entre tareas. Los constructores de comunicación incluyen aquellos para envío y recepción de estructuras de datos así como primitivas de alto nivel, tales como emisión, barreras de sincronización y sumas globales. SSI:single system image Administración Job (tarea o trabajo): Una misma imagen del sistema. Es la propiedad de un sistema que oculta la naturaleza heterogénea y distribuida de los recursos que lo componen y los presenta, a usuarios y aplicaciones, como un único e integrado recurso computacional. Secuencia de operaciones, programa o comando requerido por un usuario para correr en un ambiente multiproceso. Job serial: Caso especial de job donde hay un solo procesador en lugar de múltiples procesos paralelos. Job inteactivo: Tarea en la cual el usuario ha iniciado una sesión en la computadora y corre trabajos sin utilizar un sistema de administración de tareas. Batch job (Proceso en lote): Consiste en una tarea sometida a través de un sistema de administración de tareas y que corre cuando los recursos requeridos se encuentran disponibles. Balanceo de carga: Lo ideal en el procesamiento en paralelo es que cada procesador realice la misma cantidad de trabajo, y además, se espera que los procesadores trabajen al mismo tiempo. La meta del balanceo de carga es minimizar el tiempo de espera de los procesadores en los puntos de sincronización. 114 ANEXO 1. Glosario de Términos Calendarización: Implica que un trabajo será despachado cuando sea satisfecha una condición de tiempo específica. Ejecución por lotes: Forma de asegurar que un sistema de cómputo permanezca activo en horas no hábiles o de poca carga de trabajo. Mecanismo efectivo que permite obtener más troughput del sistema. Redes / Conexiones Switches: Es un conjunto de puertos de entrada, un conjunto de puertos de salida y una red cruzada interna (crossbar) que conecta cada entrada a cada salida, el buffering interno, y el control lógico para efectuar la conexión de entrada y salida en cada punto de tiempo. Generalmente el número de puertos de entrada es igual al número de puertos de salida, lo cual es llamado el grado del switch. Ethernet: Protocolo de comunicación basado en el estándar IEEE 802.3 cuya velocidad de transmisión es de 10 Mbps. Requiere de 3 elementos básicos para su funcionamiento: un medio físico por el cual van las señales ethernet; un mecanismo de control para identificar el acceso de cada una de las interfaces ethernet hacia el bus y la secuencia de la "trama ethernet" en cuanto a bits. Entre los medios físicos se destacan el cable coaxial en sus dos variantes (grueso y delgado), el par trenzado (UTP) y la fibra óptica. El par trenzado goza de más popularidad por ser más económico y de confiabilidad aceptable. El mecanismo de control que asigna el acceso al bus ethernet es conocido como CSMA/CD (Carrier Sense Multiple Access with Collision Detection), cuya sencilla explicación se basa en que el bus es compartido por todos los equipos conectados a él; cuando una interfase manda un paquete, si el medio (bus ethernet) se halla libre, entonces es transmitido. Una colisión ocurre cuando dos interfaces ethernet mandan al mismo tiempo y al mismo bus un paquete, es entonces cuando se vuelve a reenviar la información. El Frame o Trama Ethernet es un conjunto de bits ordenados en distintos campos entre los que destaca el campo de la dirección física de 48 bits o MAC addreess; el campo de datos varía de longitud de 46 a 1500 butes; 32 bits para identificar la IP (protocolo IP). Existen otros protocolos como ARP y RARP que tienen sus respectivos campos en la trama ethernet. Fast Ethernet: El protocolo Fast Ethernet es similar en cuanto a operación al descrito como ethernet y se basa de igual manera en el estándar IEEE 802.3. La principal novedad es el incremento en la velocidad de transmisión a 100 Mbps. Los medios normalmente utilizados son el par trenzado y la fibra óptica; debido al costo, es mayormente usado el par trenzado debido a su menor costo. 115 ANEXO 1. Glosario de Términos Por fortuna, la mayoría de los fabricantes están considerando en sus productos (switches, concentradores, tarjetas de red, etc.) convivan con el ethernet tradicional. Cabe mencionar que para fast ethernet se consideró un mecanismo adicional para el control de acceso aparte del CSMA/CD, dicha novedad se basa en "prioridad por demanda". Esto funciona para las "tramas ethernet" y se hizo extensiva para las tramas de token ring. Su aplicación a los clusters es poca debido a los nuevos estándares existentes ya en el mercado. Gigabit Ethernet: Es el protocolo de la familia ethernet que alcanza la velocidad de 1000 Mbps. El estándar correspondiente es el IEEE 802.3z. Los medios físicos que lo soportan son el par trenzado de categoría 5 y la fibra óptica unimodo y multimodo soportando los modos de full y half-duplex. Sigue utilizando el mecanismo de control de acceso de CSMA/CD. Ya es una buena opción para utilizarlo como backbone y para aplicaciones de ancho de banda grande al escritorio. La aceleración de la velocidad de transmisión fue resultado de mezclar los estándares 802.3 y el ANSI X3 T11 Fiber Channel. Una adición de gigabit ethernet es conocida como "frame bursting" que consiste en permitir a una estación transmitir una ráfaga de frames sin ceder el control. El modo full duplex se está utilizando en mayor medida en los equipos de mayor capacidad como swhitches, grandes servers o routers, dicha capacidad da la opción de incrementar el ancho de banda a 2 Gbps para enlaces punto a punto y de eliminar el control de flujo CSMA/CD ya que no existen colisiones. Esta última característica ees ideal para la conectividad en clusters. FDDI (Fiber Distributed Data Interface): El estándar FDDI tiene su mayor uso en backbone y en conexiones de alta velocidad en redes de área local. La topología de FDDI es similar al token ring con la diferencia que se tiene con un doble anillo. El anillo primario es usado para la transmisión de datos y el secundario como respaldo. El medio de transmisión es la fibra óptica en sus dos modos (unimodo y multimodo). En cuanto a los tipos de transmisión en FDDI existe el síncrono y el asíncrono (pueden convivir ambos tipos), el primero de ellos se utiliza para la transmisión continua de información como voz y video; el asíncrono permite manejar el ancho de banda en un esquema de 8 niveles de prioridad. El anillo secundario o de respaldo es el método para tolerar fallas en el sistema. Para su implementación, se cuenta con dispositivos conocidos como "bypass" los cuales hacen la función de aislar fallas y hacer uso del anillo de respaldo para que la comunicación no se pierda. A diferencia del ethernet, la unidad de comunicación es el token, que es quien lleva la información a través del FDDI, entregando y recibiendo paquetes. La trama del FDDI incluye al Token con 3 campos (preambulo, delimitador de comienzo y el control de la 116 ANEXO 1. Glosario de Términos trama). A continuación siguen los campos de direccion destino y dirección origen para seguir con el campo de datos. Existe un campo que realiza la verificación de la información a través de un CRC (Cyclic Redundancy Check) y que en el FDDI es mejor conocido como el FCS (Frame Check Sequency). Finalmente están los campos que delimitan el fin de la trama y del estado de la trama. SCI (Scalable Coherent Interface): Herramientas Depurador (Debugger): Es un estándar que fue concebido para incrementar el ancho de banda de los buses en blackplane. Está basado en la tecnología de conexiones punto a punto que elimina muchos de los problemas físicos proporcionando velocidades mayores. SCE, de hecho, simula un bus, dando los mismos servicios que un bus (incluso otros que normalmente no se ofrecen) pero sin usar buses. La configuración básica de SCI es un anillo que contiene varios nodos conectados entre si por enlaces (links) unidireccionales punto a punto. Cada aplicación se conecta a SCI a través de un nodo, el cual es visto por la aplicación como un bus convencional. Los nodos, a su vez, se enlazan entre si con links punto a punto a velocidad muy alta ya que no tienen las limitaciones de los blackplanees. Cada nodo está conectado al anillo SCI por un link (SCI IN) proveniente del nodo precedente y por otro link (SCI OUT) con destino al nodo siguiente y, a su vez, está conectado con la aplicación normalmente por el bus propio. Cuando un paquete que circule por el anillo llegue al nodo, el address decoder verá si el paquete es para ese nodo o no. En caso de que si lo sea lo encaminará a la Fifo de entrada, en el caso contrario, lo ser´ hacia la "bypass Fifo", o sea, hacia el anillo SCI. El codificador/decodificador de paquetes transformará el paquete entrante en el formato del bus y se usa para comunicar en ambos sentidos con la aplicación. Cuando se mande un paquete de salida a SCI, éste irá a la Fifo de salida y si no hay ningún paquete mandándose en ese momento, desde la bypass Fifo, el paquete será encaminado hacia el link de salida. Es un estándar que permite a sistemas crecer con componentes modulares de diferentes vendedores. El flujo de datos es de 1 Gbyte/s. El estándar SCI usa memoria compartida. Software que permite revisar la ejecución instrucción por instrucción de un programa y se utiliza cuando se detecta un mal funcionamiento en el programa. Depurar programas paralelos es una tarea difícil debido a su naturaleza concurrente. Un depurador para programas paralelos debe proporcionar control sobre todos los procesos del programa, y además ser capaz de presentar la información de forma concisa. Almacenamiento 117 ANEXO 1. Glosario de Términos RAID (Redundant Array of Inexpensive Disks): ¿Qué es openMosix? En un cluster existe una gran cantidad de recursos, tradicionalmente cada nodo no puede acceder a la totalidad de recursos. Los procesos corriendo en un nodo sólo pueden acceder a los recursos locales. Antes para accesar a recursos remotos, el mecanismo no era simple ni transparente. Por ejemplo, para acceder a archivos en un disco remoto era a través de ftp. La idea ahora es distribuir los datos entre los discos de tal forma que se puedan acceder, en lo posible, en varios discos al mismo tiempo. La primera vez que se uso esta idea no fue para un cluster sino para construir un "disco único" con un gran ancho de banda, conectando varios discos a un controlador y dar la impresión de que el "disco" tenía un más alto ancho de banda para transferencia de datos. Este tipo de discos se conoce como RAID. El sistema openMosix es una extensión del kernel del sistema operativo GNU/Linux que amplía grandemente sus posibilidades en computación paralela, a la vez que implementa una arquitectura SSI. 118 ANEXO 2. Errores más frecuentes al compilar e instalar el kernel ANEXO 2. Errores más frecuentes al compilar e instalar el kernel Los errores más frecuentes a la hora de configurar el kernel de openMosix son: • • • • Las aplicaciones no migran de todos los nodos a todos los nodos: La causa de este error suele ser que se ha omitido poner en todas las máquinas el mismo tamaño máximo de memoria. El parche no se aplica correctamente: Se tiene que usar un vanilla kernel, es decir, un kernel tal y como Linus Torvalds lo distribuye. Particularmente, los kernels que vienen con las distribuciones de Linux ya están demasiado parcheados. No existe el directorio/proc/hpc: O no se ha arrancado con el kernel openMosix, o se ha olvidado activar la primera opción de openMosix process migration support al compilar el kernel. Uso la ultima versión del gcc, y el kernel de openMosix no compila: No es un problema de openMosix, es un problema del kernel de Linux. Cualquier versión de gcc que compile el kernel de Linux compila el kernel de openMosix; y casi todas las distribuciones de Linux modernas traen un paquete con una versión del backend de gcc para compilar el kernel de Linux. Además de estos problemas, se tendrán los problemas habituales de instalar un kernel nuevo: olvidar el ejecutar el comando lilo, olvidar el instalar los módulos, etc; de cualquier forma, si se sabe recompilar el kernel e instalar un kernel nuevo no se tendrá ningún problema con el kernel de openMosix. (miKel & Buytaert, 2004) 119 ANEXO 3. Instalación de las herramientas de área de usuario ANEXO 3. Instalación de las herramientas de área de usuario Para configurar e instalar correctamente las herramientas de área de usuario no es necesario recompilar el kernel de openMosix; pero es fundamental tener descargado el kernel de openMosix, ya que se necesitaran sus cabeceras para compilar correctamente las herramientas de área de usuario. El primer paso para instalar las herramientas de área de usuario del proyecto openMosix es descargarlas. Un lugar donde se pueden descargar las herramientas de área de usuario es http://www.orcero.org/irbis/openmosix o de Sourceforge. Se descarga la última versión y se descomprime con: tar -zxf openMosixUserland-0.2.4.tgz, se entra al directorio creado: cd openMosixUserland-0.2.4, se recomienda que se lea el archivo de instalación: cat Installation | more Configurando las herramientas de área de usuario El paso siguiente para configurar las herramientas de área de usuario será editar el archivo configuration con un editor de textos. Hay una opción que se debe modificar obligatoriamente si se quiere recompilar openMosix y otras opciones que no se deben tocar salvo que se este muy seguro de lo que se quiere hacer. Para una instalación estándar de openMosix en los directorios estándares apenas se debe modificar el valor de la variable OPENMOSIX. Esta variable debe contener el camino completo absoluto -no el camino relativo- del kernel de openMosix. Por ejemplo, /usr/src/openmosix es un camino válido, y /home/irbis/openMosix/linux-openmosix también lo es. ../../linux-openmosix no es un camino válido, ya que es un camino relativo y debe ser un camino absoluto. En casi todos los casos, solo se tiene que hacer: make all y los Makefile que acompañan a openMosix se encargarán de: compilarán e instalarán las herramientas de área de usuario de openMosix y sus páginas del manual. A pesar de que el código nuevo tiene muy pocos warnings y no tiene errores -al menos, que se sepa-, el código antiguo heredado de Mosix esta programado de una forma muy poco ortodoxa, por lo que hay activadas todas las opciones de warning para buscar los errores existentes en el código y eliminarlos. Una vez que la ejecución del make all esté terminada, las herramientas de área de usuario estarán instaladas y bien configuradas. Otras opciones de configuración Otras opciones del archivo configuration son: MONNAME: nombre del programa monitor de openMosix. El programa monitor del proyecto Mosix se llamaba mon, lo que era un problema ya que compartía nombre con una herramienta muy común en Linux de monitoreo del sistema. La gente de Debian lo solucionó cambiando el nombre de la aplicación para Debian de mon a mmon; pero en openMosix la aplicación se llama mosmon. En principio, es recomendable dejarlo en mosmon, salvo que por razones de compatibilidad inversa con algun script de Mosix se quiera llamar a esta aplicación mon o mmon. CC: Nombre del compilador de C. Casi siempre es gcc. INSTALLBASEDIR: Ruta completa absoluta donde está el directorio raíz del sistema de archivos donde se quiere instalar openMosix. Casi siempre es / . INSTALLEXTRADIR: Ruta completa absoluta donde está el directorio donde están los directorios con las aplicaciones del sistema y su documentación donde queremos instalar openMosix. Casi siempre es /usr . INSTALLMANDIR: Ruta completa absoluta donde está el directorio donde están las páginas del manual donde queremos instalar openMosix. Casi siempre es /usr/man . CFLAGS: Opciones de compilación en C para las herramientas de área de usuario. Las opciones -i./, -i/usr/include y i$(OPENMOSIX)/include son obligatorias; el resto se pondrá según el interés particular de cada quien -las opciones por defecto que se encuentran en el archivo de configuración son válidas y se deben mantener salvo que haya una buena razón para no hacerlo. (miKel & Buytaert, 2004) 120 ANEXO 4. Errores frecuentes en la compilación e instalación de las herramientas. ANEXO 4. Errores frecuentes en la compilación e instalación de las herramientas • Hay un conjunto de errores en la instalación de las herramientas de área de usuario que se deben conocer bien, ya que son preguntas frecuentes: Las herramientas de área de usuario no compilan: ¿Hemos puesto correctamente el valor de la variable OPENMOSIX en el archivo configuration? ¿Esta variable realmente apunta al kernel de openMosix? ¿Es realmente el kernel de openMosix, o un kernel normal? Recordar que la variable OPENMOSIX debe ser forzosamente un camino absoluto. Por último, ¿tenemos instalado un compilador de C? • Error This is not Mosix! Este error se da cuando se usan las herramientas de área de usuario del proyecto Mosix sobre un kernel normal o sobre un kernel openMosix. También se da si se usa el setpe de una versión de las herramientas de área de usuario anterior a la 0.2.4 sobre un kernel que no tiene soporte openMosix. Si es este último caso, es muy recomendable usar una versión de herramientas de área de usuario 0.2.4 o posterior; la 0.2.4 es conocida por ser realmente estable, y no hay ninguna razón objetiva para usar una versión anterior. En cualquier otro caso, recordar que las herramientas de área de usuario del proyecto Mosix no son libres; y que, no funcionan en openMosix. • Error This is not openMosix! Este error se da cuando se usan las herramientas de área de usuario de openMosix en un equipo que no está usando un kernel con soporte openMosix. O se esta usando las herramientas de área de usuario de openMosix sobre un kernel Mosix o no se ha arrancado con el kernel nuevo o el kernel nuevo no tiene soporte a migración de procesos openMosix. (miKel & Buytaert, 2004) 121 ANEXO 5. Configurando la topología del cluster ANEXO 5. Configurando la topología del cluster Una vez que se tiene instalado el kernel de openMosix y las utilidades de área de usuario de openMosix, el siguiente paso es configurar la topología del cluster. Para configurar la topología del cluster openMosix se siguen dos procedimientos distintos. • • El primero es el procedimiento tradicional, consistente en un archivo por nodo donde se especifican las IPs de todos los nodos del cluster. El segundo procedimiento consiste en emplear el demonio de auto detección de nodos. Cada procedimiento tiene sus ventajas y sus inconvenientes. La configuración tradicional manual tiene como inconveniente que es más laboriosa en clusters grandes: cada vez que se quiere introducir un nodo nuevo en el cluster, se debe tocar el archivo de configuración de todos los nodos de dicho cluster para actualizar la configuración. Este método permite, por otro lado, tener topologías arbitrariamente complejas y grandes; también es considerado el método más eficiente. El segundo método para configurar los nodos de un cluster openMosix es usar el demonio de detección automática de nodos, el omdiscd. Este método es el más cómodo, ya que el cluster casi se configura solo. Por otro lado, tiene dos inconvenientes: 1. 2. la primera, que todas las máquinas del cluster deben estar en el mismo segmento físico. Esto impide que el demonio de auto detección pueda ser usado en redes muy complejas. La segunda, que todos los nodos cada cierto tiempo deben mandar un paquete de broadcast a todos los otros nodos de la red para escanear los nodos openMosix de la red. Para pocos nodos, estos paquetes no afectan al rendimiento; pero en caso de cluster de tamaño medio o grande, la pérdida de rendimiento puede ser crítica. Realmente el demonio de autodetección de nodos no detecta nodos openMosix, sino que detecta otros demonios de autodetección de nodos. Esto significa en la práctica que el demonio de autodetección de nodos no es capaz de detectar nodos openMosix configurados mediante el método manual. Tampoco se debe mezclar los dos tipos de configuración en el cluster, ya que esto dará dolores de cabeza en la configuración de la topología. Configuración automática de topología La forma automática de configurar la topología de un cluster openMosix es mediante un demonio recientemente incorporado en las herramientas de área de usuario, que permite la detección automática de nodos del cluster. El nombre del demonio es omdiscd. Para ejecutarlo: omdiscd y este programa creará automáticamente una lista con las máquinas existentes en la red que tienen un demonio de auto detección de nodos válido y funcionando correctamente, e informará al kernel openMosix de estas máquinas para que las tenga en cuenta. Se pueden consultar la lista generada por el demonio de auto detección de nodos con el comando: showman; este comando muestra una lista de los nodos que han sido dados de alta en la lista de nodos local al nodo que ejecuta el demonio omdiscd. El hecho de que un nodo sea reconocido por un segundo no implica el caso recíproco: alguno de los nodos de la lista pueden no haberse reconocido aún como nodo válido del cluster. Se puede informar a openMosix sobre por cual de los interfaces de red se quiere mandar el paquete de broadcast. Esto es especialmente interesante en el caso particular de que el nodo donde se lanza el demonio de auto detección de nodos no tenga una ruta por defecto definida, caso en el que omdiscd parece fallar para algunos usuarios; aunque hay otros escenarios donde también es necesario controlar manualmente por que interfaz de red se manda el paquete de broadcast. Para forzar a omdiscd a mandar la información por un interfaz en particular se tiene que usar la opción -i. Por ejemplo, llamamos al demonio de auto detección de nodos en este caso con el comando: omdiscd -i eth0,eth2; lo que significa que se manda el paquete de broadcast por eth0 y por eth2; y solamente por estas dos interfaces de red. Otro caso particular que es interesante conocer es el de algunas tarjetas PCMCIA que por un error en el driver del kernel no sean capaces de recibir correctamente los paquetes de broadcast. La única solución que se puede tener en la actualidad es poner el interfaz de dicha tarjeta con un mal driver en modo promiscuo, con lo que la tarjeta leerá y analizará todos los paquetes, incluidos los de broadcast; y el así el kernel podrá acceder a dichos paquetes de broadcast. No es un problema del código de openMosix, sino de los drivers de algunas tarjetas; pero el demonio de autodetección de nodos lo sufre directamente. Ponemos la tarjeta con un driver que tenga problemas con los paquetes de broadcast en modo promiscuo con: ifconfig eth0 promisc; suponiendo que eth0 es la interfaz de red. En otro caso, se sustituye eth0 por el interfaz de red. En caso de que la computadora tenga varias interfaces de red, se usa esta instrucción con todas aquellas interfaces por los que se espera recibir paquetes de openMosix y que tengan este problema. Sólo root puede poner en modo promiscuo una interfaz. 122 ANEXO 5. Configurando la topología del cluster Para verificar con comodidad el auto detección viendo que hace el demonio de auto detección de nodos, podemos lanzarla en primer plano con la opción -n, con la sintaxis: omdiscd –n; así se lanzará en primer plano, y se vera en todo momento lo que está pasando con el demonio. Otro modificador que es interesante conocer en algunos escenarios es -m. Lleva como parámetro un único número entero, que será el TTL de los paquetes de broadcast que se envió a otros demonios de auto detección de nodos. Configuración manual de topología El sistema de auto detección tiene muchos problemas que lo hacen inconveniente para determinadas aplicaciones. No funciona si hay algo entre dos nodos que bloqueen los paquetes de broadcast, puede sobrecargar la red si tenemos muchos nodos en el cluster, supone un demonio más que debe correr en todos los nodos del cluster, lo que complica la administración; y, quizás lo más importante, aún es software beta y no siempre detecta todos los nodos. Por todo ello, muchas veces un archivo compartido de configuración, común a todos los nodos, es la solución más simple a ese problema. En openMosix se llama al archivo /etc/openmosix.map. El script de arranque de openMosix lee este archivo y lo utiliza para informar al kernel de openMosix sobre cuales son los nodos del cluster. El archivo /etc/openmosix.map contiene una lista con los rangos de direcciones IP que pertenecen al cluster. Además de indicar que rangos de direcciones IP pertenecen al cluster, permite asignar un número de nodo único a cada IP de la red. Este número será empleado internamente por el kernel de openMosix y por las herramientas de usuario; también se emplea como identificador en comandos como migrate para referenciar de forma unívocamente cada nodo. Tanto el sistema de archivos /proc/hpc como las herramientas de área de usuario usan estos números identificativos de nodo, en lugar de la IP, ya que un nodo del cluster openMosix puede tener más de una IP y solo uno de estos números. Cada línea del archivo /etc/openmosix.map corresponde a un rango de direcciones correlativas que pertenecen al cluster. La sintaxis de una línea es: numeronodo IP tamañorango Donde: numeronodo es el primer número de la primera IP del rango, IP es la primera IP del rango, y tamañorango es el tamaño del rango. Por ejemplo, en el archivo /etc/openmosix.map con el contenido: 1 10.1.1.100 16 17 10.1.1.200 8 Se esta diciendo que el cluster openMosix tiene 24 nodos. En la primera línea se dice que los 16 nodos primeros, que se comenzaron a numerar por el número 1, comienzan desde la IP 10.1.1.100; y continúan con 10.1.1.101, 10.1.1.102... así hasta 10.1.1.115. En la segunda línea se dice que, comenzando por el nodo número 17, tenemos 8 nodos más; comenzando por la IP 10.1.1.200, 10.1.1.201...hasta la IP 10.1.1.207. Se puede también incluir comentarios en este archivo. A partir del carácter #, todo lo que siga en la misma línea del carácter # es un comentario. Por ejemplo, se puede escribir: # redes 10.1.1 1 10.1.1.100 16 # Los 16 nodos del laboratorio 17 10.1.1.200 8 # Este archivo es exactamente igual para openMosix que el archivo anterior. La sintaxis de la declaración de la topología del cluster en el archivo /etc/openmosix.map necesita una explicación adicional cuando tenemos alguna máquina con más de una dirección IP. En este archivo deben aparecer todas las IPs que puedan enviar y recibir paquetes openMosix, y sólo ellas. Esto significa que no se pondrá en este archivo las IPs que no se usen para enviar y recibir los mensajes; pero también supone un problema cuando una misma máquina puede enviar y recibir mensajes de openMosix por varias IPs distintas. Por todo esto, para solucionar el problema de que un nodo tenga varias direcciones IPs válidas en uso en el cluster openMosix, se tiene la palabra clave ALIAS, que se usa para indicar que la definición de la dirección IP asignada a un número identificador de nodo está replicada porque dicho identificador tiene más de una IP válida. 123 ANEXO 5. Configurando la topología del cluster Ejemplo: un nodo particular en un cluster -el nodo 8- comparte simultáneamente una dirección de las 10.1.1.x y otra de las 10.1.2.x. Este segmento 10.1.2.x tiene a su vez más nodos openMosix con los que se tiene que comunicar. Se Tendría el archivo: # redes 10.1.1 1 10.1.1.100 16 # Los 16 nodos del laboratorio 17 10.1.1.200 8 # # redes 10.1.2 18 10.1.2.100 7 8 10.1.2.107 ALIAS # Nodo de interconexión con la red 10.1.1 25 10.1.2.108 100 es decir, se esta definiendo la IP del nodo 8 dos veces. La primera vez en la línea: 1 10.1.1.100 16 # Los 16 nodos del laboratorio y la segunda vez en la línea: 8 10.1.2.107 ALIAS # Nodo de interconexión con la red 10.1.1 en la primera línea el nodo 8 está definido dentro del rango entre el nodo 1 y el nodo 16. En la Segunda línea se ve como se dice con ALIAS que el nodo 8, además de la IP ya definida, tiene una IP adicional: la IP 10.1.2.107. Al usar ALIAS: se tiene que separar forzosamente la IP de la entrada ALIAS del rango donde esta ha sido definida. Por ejemplo, es erróneo hacer: # redes 10.1.1 1 10.1.1.100 16 # Los 16 nodos del laboratorio 17 10.1.1.200 8 # # redes 10.1.2 18 10.1.2.100 108 8 10.1.2.107 ALIAS # Nodo de interconexión con la red 10.1.1 Esto no funciona, ya que definimos un identificador para la IP 10.1.2.107 dos veces. Por ello, tenemos que resolver este escenario como en el ejemplo completo anteriormente comentado. Por último, se debe tener presente que todos los nodos del cluster openMosix deben tener el mismo archivo /etc/openmosix.map, y de que la dirección local 127.0.0.1, por lo tanto, jamás debe aparecer en el archivo /etc/openmosix.map, ya que los archivos deben ser iguales; y, en caso de incluir la dirección IP local 127.0.0.1, cada archivo asignaría al mismo número distinto una máquina distinta. El script de inicialización En openMosix se tiene un mejor procedimiento para configurar la topología del cluster: su script de inicialización. En el directorio de instalación de las herramientas de área de usuario se tiene un subdirectorio llamado scripts. En este directorio hay un script que se llama openmosix, que es el script encargado de configurar el nodo cuando este entre en el runlevel que se determine, Para activarlo, se entra en el directorio scripts y se hace: cp openmosix /etc/rc.d/init.d después se tiene que decidir en qué runlevels se quiere lanzar openMosix. Si se quisiera lanzar openMosix en el runlevel 3, se hace: ln -s /etc/rc.d/init.d/openmosix /etc/rc.d/rc3.d/S99openmosix y si se quiere lanzar en el runlevel 5: ln -s /etc/rc.d/init.d/openmosix /etc/rc.d/rc5.d/S99openmosix Si se quiere lanzar openMosix al arrancar una máquina, se debe determinar cual es el runlevel de arranque del nodo. Para saber cual es el runlevel de arranque de la máquina en la que se está trabajando, se hace: cat /etc/inittab | grep :initdefault: ó cat /etc/inittab | grep id: 124 ANEXO 5. Configurando la topología del cluster mostrará algo como: id:5:initdefault:, en este caso, el runlevel de arranque será el 5, y será el runlevel donde se tendrá que activar el script de openMosix . Por otro lado, si sale: id:3:initdefault:, el runlevel de arranque será el 3. Cuando se vuelva a arrancar la máquina, openMosix estará correctamente configurado. De cualquier forma, se puede en cualquier momento reiniciar la configuración de openMosix sin reiniciar la máquina haciendo: /etc/rc.d/init.d/openmosix restart Migrando tareas En principio, los procesos migrarán solos según el algoritmo de equilibrado automático de carga. Sin embargo, se puede recomendar una migración o en forzar que un proceso vuelva a su nodo raíz. Para ello se tienen que utilizar las utilidades de área de usuario y una de las utilidades es la migarte, la que permite controlar las migraciones: Esta utilidad permite solicitar la migración de un proceso determinado a un nodo determinado. Su sintaxis es: migrate PID numnodo donde PID es el PID del proceso, y numnodo el número del nodo al que se quiere que el proceso migre. Si se desea que se forzara el proceso para que migre a su nodo raíz, se hace: migrate PID home por otro lado, si se quiere que el proceso migre a un nodo indeterminado que el kernel de openMosix debe decidir según el algoritmo de equilibrado automático de carga, se hace: migrate PID balance Sólo puede solicitar la migración de una tarea root, el usuario propietario de la tarea y el usuario efectivo de la tarea. La migración es solo solicitada; y la tarea puede no migrar si hay alguna razón de fuerza mayor que impida la migración. Particularmente, la única migración de cualquier proceso que se tendra con completa seguridad de que se realizará es la migración al nodo raíz con el parámetro home. Las otras pueden no ocurrir. (miKel & Buytaert, 2004) 125 ANEXO 6 Las herramientas de área de usuario ANEXO 6 Las herramientas de área de usuario Monitoreando el cluster La herramienta usada para monitorear un cluster openMosix es mosmon. Esta herramienta permite ver un gráfico de barras con la carga asociada a cada nodo del cluster. Esta información se puede obtener haciendo un top en cada uno de los nodos, pero para cluster de varios nodos la solución del top es inviable; pero aun así mosmon es una solución buena. mosmon es una utilidad especialmente interesante por varios puntos adicionales, que no todos sus usuarios conocen y que lo hacen indispensable para cualquier administrador de sistemas: se pueden ver las barras de forma horizontal y vertical, se pueden listar todos los nodos definidos en el cluster, estén o no activos, se puede ver el número de nodos activos y además, en caso de que el número de nodos sea mayor del que se puede ver en una pantalla, con el cursor derecho y el cursor izquierdo se puede mover un nodo a la derecha o un nodo a la izquierda, con lo que se puede ver grandes cantidades de nodos en una pantalla cualquiera. Todo esto hace a mosmon una herramienta realmente imprescindible para el administrador del cluster. De entre las opciones disponibles que se pueden usar al llamar a mosmon, las más importantes son: -d: incluye en el gráfico todos los nodos, incluso aquellos que están desactivados. Esta opción es muy útil, ya que así el administrador ve cuando entran en el cluster estos nodos desactivados. -t: lista el número de nodos activos del cluster. Esta opción es especialmente útil en clusters grandes o muy grandes. Una vez que se entra al programa mosmon, con la pulsación de algunas teclas podemos se consiguen funciones extras. De entre las teclas activas de mosmon, se listan: d: lista también aquellos nodos que no están activos. Hace lo mismo que arrancar mosmon con la opción -d. D: lista sólo aquellos nodos que están activos. Por ello, hace lo mismo que arrancar mosmon sin la opción -d. h: muestra la ayuda de mosmon. l: permite visualizar la carga de cada nodo. Este es el modo de visualización con el que arranca mosmon, por lo que esta opción se usa para volver a la visualización de carga después de haber cambiado la vista con m, r, s, t ó u. m: permite visualizar la memoria lógica usada por los procesos -lo que corresponde a suma de las memoria que los procesos creen que realmente usan- y la memoria total por cada máquina, en lugar de la carga. La barra corresponde con la memoria lógica ocupada, mientras que los +, sumados a la barra, corresponden a la memoria total. Los + corresponden a la suma entre la memoria libre y la memoria usada por cosas distintas de los procesos -kernel, Reservada por dispositivos hardware-. Puede ser menor ó mayor que la memoria libre real, ya que por un lado varios procesos pueden compartir segmentos, lo que hace que la memoria física usada sea menor que la memoria lógica usada; por otro lado, el kernel y los dispositivos hacen que no toda la memoria no usada por los procesos esté realmente libre. Todas las cantidades se muestran en megabytes. q: sale del programa mosmon. r: permite visualizar la memoria física usada, la memoria libre y la memoria total por cada máquina, en lugar de la carga. La barra corresponde con la memoria física usada en un nodo, mientras que los + corresponden a la memoria libre. Por ello los +, sumados a la barra, corresponden a la memoria total. Todas las cantidades se muestran en megabytes. s: permite ver las velocidades de los procesadores y el número de procesadores por cada máquina en lugar de la carga. t: lista un el número de nodos activos del cluster, si no está visible ó desactiva la visión si se están viendo el número de nodos activos del cluster. Está relacionado con la opción de arranque -t. u: permite ver el grado de utilización del procesador de cada nodo. En el caso de que el cuello de botella de un nodo esté en su procesador, este valor estará al 100%. Hay que destacar que un nodo puede estar saturado por muchas cosas, tales como acceso a disco o a swap, y no llegar dicho nodo al 100% de la utilización neta del procesador. Un valor por debajo del 100%, por lo tanto, significa que un procesador está infrautilizado, por lo que podría aceptar migraciones de entrada -aunque puede tener migraciones de salida del nodo de procesos que usen demasiada memoria o bastante espacio en disco-. Además de todo esto, la tecla Enter permite redibujar la pantalla, p hace lo mismo que el cursor izquierdo -mover la vista de nodos a la izquierda-, y n permite hacer lo mismo que el cursor derecho -mover la vista de nodos a la derecha-. 126 ANEXO 6 Las herramientas de área de usuario Configurando los nodos en openMosix La herramienta para configurar los nodos de un cluster openMosix es setpe. Esta herramienta es llamada por los scripts de inicialización y parada de openMosix, así como por numerosos scripts de openMosix y herramientas auxiliares. setpe se encarga de determinar la configuración de nodos del cluster. Su parámetro principal es el archivo donde estará especificado el mapa de nodos. setpe habitualmente es llamado de tres formas; la primera es con el modificador -f nombrearchivo, que tomará como archivo de configuración nombrearchivo. La segunda forma es pasando como parámetro -, en cuyo caso leerá el archivo de configuración de la entrada estándar. Esto es útil para hacer pruebas de configuración, o para hacer pipes de setpe con otras aplicaciones. Por último, puede ser llamado con un único parámetro, -off, para sacar el nodo del cluster. De entre los parámetros de setpe se destacan: -w: carga la configuración del archivo indicado con los parámetros especificados en dicho archivo sobre el kernel, si es posible hacerlo sin necesidad de reinicializar la parte de openMosix del kernel. Esto significa que sólo actualiza la configuración si el nodo no ejecuta ningún proceso de otro nodo, ni ningún proceso del nodo local se ejecuta en un nodo remoto. En cualquiera de estos dos casos, -w dará un error y no actualizará la configuración. -W: carga la configuración del fichero indicado con los parámetros especificados en dicho archivo sobre el kernel, tenga que hacer lo que deba que hacer. Esto puede significar expulsar procesos y mandarlos a sus nodos de vuelta, así como traerse al nodo local todos los procesos remotos lanzados localmente. Internamente, con un -W, realmente setpe hace primero un -off y después hace un -w. -c: realiza toda la operativa que realizaría -w, solo que no graba el resultado en el kernel. Esta opción es útil para verificar una configuración sin instalarla en la máquina. Cualquiera de estas tres opciones puede ser acompañada por la opción -g número. Si se utiliza, septe informará al kernel que el número máximo de gateways que se interponen entre el nodo local y el más remoto de los nodos es, número. Si no se indica esta opción, simplemente no se modifica el parámetro del kernel de número máximo de gateways, quedando como estaba. El número máximo de gateways intermedio que se puede especificar es 2. Además de estas opciones, hay otras de setpe. Que son: -r: lee la configuración del nodo actual, y la vuelca en la salida estándar ó en un archivo determinado con la opción -f nombrearchivo. Esta opción es muy útil para ver errores en la configuración en clusters muy grandes. -off: esta opción desactiva openMosix en el nodo actual, es decir, bloquea las migraciones de salida de procesos locales, bloquea las migraciones de entrada de procesos remotos, manda las tareas que se ejecutan en el nodo actual de otros nodos de vuelta a sus nodos de origen, llama a los procesos remotos originados en el nodo local para que vuelvan, borra la tabla de nodos del nodo, y, por último, inhabilita openMosix en el nodo local. Controlando los nodos con mosctl Del mismo modo que setpe permite ver la configuración de un nodo openMosix y configurarlo, mosctl permite editar el comportamiento de un nodo ya configurado y verlo. De entre las opciones del comando mosctl, se mencionan: block: en el nodo local, bloquea la entrada de los procesos generados en otro nodo. noblock: deshace los efectos de block. mfs: activa el soporte a MFS en openMosix. nomfs: inhabilita el soporte a MFS en openMosix. lstay: bloquea la migración automática hacia fuera de los procesos generados localmente. nolstay: deshace los efectos de lstay. stay: bloquea la migración automática hacia fuera de cualquier proceso. 127 ANEXO 6 Las herramientas de área de usuario nostay: deshace los efectos de stay. quiet: el nodo local no informará a los otros nodos de su status. noquiet: deshace los efectos de quiet. Como se observa, todas estas opciones tienen un modificador que habilita alguna propiedad y otro modificador que la inhabilita. Hay otros modificadores de un solo comando para mosctl, que son: bring: trae de vuelta a todos los procesos que se han generado localmente pero que se ejecutan en un nodo remoto. Además, internamente realiza primero la misma operación que lstay, y deja el estado en lstay. No retorna hasta que no han vuelto todos los procesos remotos generados localmente. expel: manda de vuelta a sus nodos de origen a todos los nodos que se ejecutan en el nodo local pero fueron generados en un nodo remoto. Además, internamente realiza primero la misma operación que block, y deja el estado en block. No retorna hasta que no han salido todos los procesos remotos del nodo local. Por ejemplo, para apagar computadoras un nodo en un cluster openMosix sin perder ningún proceso, se debe hacer: mosctl expel mosctl bring Después de estos comandos, el nodo no aceptará ni que migren al nodo local procesos generados en un nodo externo, ni que ningún nodo local migre a otro nodo. Además, no se ejecutará ningún proceso remoto en el nodo local ni ningún proceso local en el nodo remoto. Es decir, máquina principal está desligada del cluster openMosix, por lo que si se apaga la máquina no afectará al resto del cluster. Existen, además de estos, un conjunto de modificadores que tienen un parámetro adicional: el identificador de un nodo dentro del cluster. Estos modificadores permiten obtener información sobre cualquier nodo del cluster. Estos modificadores son: getload nodo: siendo nodo un nodo válido en el cluster, este modificador devuelve la carga que actualmente tiene dicho nodo. Este parámetro de carga no corresponde al parámetro de carga del kernel al que se acostumbra, sino al parámetro de carga que calcula openMosix y usa openMosix. getspeed nodo: da la velocidad relativa de dicho nodo. Esta velocidad es relativa, y se supone que un Pentium-III a 1GHz es un procesador de 1000 unidades de velocidad. getmem nodo: da la memoria lógica libre y la memoria lógica total de un nodo particular del cluster. getfree nodo: da la memoria física libre y la memoria física total de un nodo particular del cluster. getutil nodo: siendo nodo un nodo válido en el cluster, nos da el grado de uso de dicho nodo en el cluster. isup nodo: indica si el nodo indicado está activo o no. getstatus nodo: nos dará el estado del nodo indicado. En este estado incluye también información sobre si el nodo permite migraciones de entrada, si permite migraciones de salida, si bloquea todas las migraciones, si está activo, y si está propagando información sobre su carga. Por último, se tiene un modificador que permite descubrir la IP y el identificador de nodo en openMosix asociado a un nodo en particular. Es: mosctl whois dirección y se puede tener como parámetro dirección el identificador de nodo, en cuyo caso este comando devolverá la IP, ó la IP, en cuyo caso devolverá el identificador de nodo ó el nombre de la máquina, en su caso devolverá el identificador de nodo. Este comando también permite indica si la máquina no pertenece al cluster openMosix. Si se llama a mosctl whois sin ningún parámetro adicional, este comando devolverá el identificador del nodo local. 128 ANEXO 6 Las herramientas de área de usuario Forzando migraciones Para forzar una migración en un cluster openMosix, se debe usar el comando migrate. El comando migrate toma dos parámetros: el primero es el PID del proceso que se quiere hacer migrar y el segundo parámetro es donde se quiere que se migre. Este segundo parámetro debe ser el identificador válido de un nodo en el cluster. Existen, sin embargo, dos parámetros que se pueden colocar en lugar del identificador válido de un nodo del cluster. Estos dos modificadores modelan dos casos especiales y son: home: fuerza a migrar a un proceso al nodo donde fue generado. balance: fuerza a migrar a un proceso al nodo donde la migración suponga minimizar el desperdicio de recursos dentro del cluster openMosix. Es una forma de indicar que se evalúe el algoritmo de migración automática de carga de openMosix, pero dando preferencia a la migración del proceso del que se ha indicado el PID. A la hora de lanzar esta migración, en caso de que el proceso sea un proceso lanzado en la máquina donde se ejecuto el comando migrate, debe ser el administrador de la máquina, el usuario propietario del proceso, el usuario efectivo del proceso, miembro del grupo propietario del proceso ó miembro del grupo efectivo del proceso. Por otro lado, el administrador del sistema de un nodo cualquiera del cluster siempre puede lanzar este comando sobre cualquier proceso que se ejecute en dicho nodo, independientemente de que se haya generado en el nodo local ó en un nodo remoto. En principio, el proceso puede no migrar aunque se le lance la orden migrate. En caso de que no migre, algunas veces se recibirá un mensaje de error avisando que el comando no funcionó, pero unas pocas veces no migrará y no se recibirá dicho mensaje. Particularmente esto se da cuando se forza una migración posible pero pésima: el proceso será mandado de vuelta al nodo local incluso antes de que salga, porque el algoritmo de optimización de carga considerará inaceptable la migración. La única migración que realmente se puede forzar siempre es la de vuelta a casa, siempre que el nodo de origen no acepte salidas de su nodos con mosctl lstay y no se bloque la entrada en el nodo de destino con mosctl block. Recomendando nodos de ejecución Cuando se lanza un proceso, se puede indicar como se va a comportar frente a la migración ó donde se prefiera que se ejecute. Para ello, se cuenta con el comando mosrun. Este comando no se suele llamar directamente, sino a través de un conjunto de scripts que facilitan su uso. Con este comando se pueden transmitir a openMosix la información sobre qué hace el proceso, información que será fundamental para que openMosix minimice el desperdicio de recursos del cluster al mínimo. También se puede indicar un conjunto de nodos entre los cuales estará el nodo donde migrará el proceso después de lanzado, si esta migración es posible. En un sistema que no sea openMosix, mosrun lanza el proceso en la máquina local de forma correcta. El comando mosrun siempre tiene la misma estructura de llamada: mosrun donde migracion tipo comando argumentos donde: nodo al que el proceso va a migrar inmediatamente después de ser lanzado, si esto es posible. migracion: si se bloquea o no el proceso en el nodo de destino. tipo: tipo de proceso que se lanzará. comando: nombre del proceso que se va a lanzar. argumentos: argumentos del proceso que se va a lanzar El modificador donde puede ser: Un nodo de destino, al que el proceso migrará inmediatamente después de ser lanzado, si esto es posible. -h, será el nodo local. -jlista: en este caso, inmediatamente después de lanzar el proceso, lo migrará a un nodo escogido aleatoriamente dentro de la lista de rangos lista. Esta lista es una lista de nodos y rangos, donde los rangos de nodos se determinan separando el menor y el mayor 129 ANEXO 6 Las herramientas de área de usuario de rango por un guión. Por ejemplo, si se indica el parámetro -j1,4-6,8,19-21, inmediatamente después de lanzar el proceso, de poder migrar el proceso, este migraría a un nodo aleatorio entre los nodos: 1,4,5,6,8,19,20 y 21. El valor de la opción de migracion puede ser: -l: el algoritmo de equilibrado automático de carga puede forzar una migración del proceso después de haber migrado dicho proceso al nodo de destino. -L: una vez migrado al nodo de destino, el proceso se quedará en él y no podrá migrar de forma automática. -k: el proceso heredará la propiedad de migrabilidad de su padre. El valor de tipo es un dato muy importante que sirve de ayuda al algoritmo de migración automática de carga, y este puede ser: -c: en un nodo de memoria infinita, el proceso tiene como cuello de botella la velocidad del procesador. -i: en un nodo de memoria infinita, el proceso tiene como cuello de botella el acceso a disco. Además de los modificadores anteriormente, con mosrun también se puede informar a openMosix sobre la forma en que openMosix debe mantener las estadísticas de uso de los recursos del sistema del proceso, datos fundamentales para que el algoritmo de equilibrado automático de carga tome decisiones correctas. Estos modificadores son: -f: mantiene las estadísticas de uso de los recursos del sistema del proceso durante poco tiempo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que tienen durante su evolución comportamientos similares durante largos periodos de tiempo. -s: mantiene las estadísticas de uso de los recursos del sistema del proceso a largo plazo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que cambian constantemente de comportamiento. -n: mantiene las estadísticas de uso de los recursos del sistema del proceso desde el principio del programa hasta su finalización. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores en procesos que están constantemente cambiando su comportamiento, y no podemos confiar en lo que hacían hace poco. Hay también un conjunto de shell scripts que ayudan a no enfrentarse contra las complejidades de mosrun al lanzar una tarea en el uso diario del cluster, y que nos permiten realizar las tareas más frecuentes de mosrun de forma cómoda. Estas utilidades tienen siempre la misma sintaxis, que es: utilidad proceso argumentos Donde utilidad es el nombre del shell script, proceso el proceso que se va a lanzar y argumentos los argumentos del proceso que lanzaremos. Las utilidades que disponemos son: cpujob: ejecuta un proceso, indicando a openMosix que si la memoria del nodo fuera infinita su cuello de botella sería el procesador. iojob: ejecuta un proceso, indicando a openMosix que si la memoria del nodo fuera infinita su cuello de botella será el acceso a disco. nomig: ejecuta un comando en el nodo local de forma que este no podrá migrar de forma automática. nunhome: ejecuta un comando de forma que preferencialmente no migrará. omrunon: ejecuta un proceso e inmediatamente después lo migra, si es posible, al nodo especificado. La sintaxis de llamada es la de lanzar un proceso directamente desde línea de comando. Útil para lanzar un proceso desde línea de comandos recomendando un nodo de ejecución. omsh: ejecuta un proceso, e inmediatamente después lo migra, si es posible, al nodo especificado. La sintaxis de llamada es la de sh como cuando se lanza el proceso con sh -c, lo que lo hace especialmente útil para sustituir a sh en shell scripts. 130 ANEXO 6 Las herramientas de área de usuario fastdecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso durante poco tiempo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que tienen durante su evolución comportamientos similares durante largos periodos de tiempo. slowdecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso a largo plazo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que cambian constantemente de comportamiento. nodecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso desde el principio del programa hasta su finalización. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores en procesos que están constantemente cambiando su comportamiento y no se puede confiar en lo que hacían hace poco. Como sucedía en el caso de mosrun, si se lanza un proceso con una de estas utilidades en una máquina sin soporte openMosix habilitado, o con este mal configurado, el proceso se lanzará perfectamente de forma local. openMosixView Es una amigable aplicación de monitorización de un cluster openMosix. openMosixView no está en las herramientas de área de usuario de openMosix por defecto. Y la razón es: las herramientas de área de usuario son lo mínimo que necesita cualquier administrador o usuario de openMosix para poder trabajar. Y en la mayor parte de las instalaciones de openMosix, la mayor parte de los nodos son cajas sin monitor, ratón o teclado con una instalación mínima de Linux, por lo que en principio openMosixView solo sería un problema para el administrador, que puede no tener interés en instalar las QT y KDE en una máquina que sólo va a servir procesos. A diferencia de las herramientas de área de usuario, que tienen una necesidad de bibliotecas y compiladores preinstalados mínima, openMosixView necesita muchas bibliotecas instaladas para ejecutarse y más aún para compilar, lo que hace poco práctico compilar y usar openMosixView en un nodo. (miKel & Buytaert, 2004) 131 ANEXO 7 Optimizando el cluster ANEXO 7 Optimizando el cluster Ayudando al algoritmo de equilibrado de carga El primer paso que se puede dar para mejorar aún más el rendimiento es ayudar al algoritmo de equilibrado de carga proveyéndole de más información sobre las características de los nodos que forman el cluster. En el caso de los clusters heterogéneos esto es fundamental; ya que se quiere que los procesos migren preferentemente a los nodos más potentes y que la migración libere a los nodos menos potentes. Tal y como queda el cluster cuando se acaba de instalar openMosix, el cluster ya optimiza el aprovechamiento de recursos en un cluster homogéneo -es decir, en el que todas las máquinas son iguales en potencia-. Sin embargo, el aprovechamiento de los recursos en un cluster heterogéneo aún no llega al óptimo. Para solucionar esto, se puede modificar la potencia relativa que un nodo considera que tiene. Hasta el momento no existe una herramienta de calibración automatizada, por lo que se debe hacer esto nodo a nodo con la herramienta manual de calibración, mosctl, con el modificador setspeed. mosctl con el modificador setspeed es una herramienta que, ejecutada sobre un nodo, permite alterar el parámetro de la potencia computacional que un nodo cree que tiene. Junto con la información de la carga, el nodo transmite también este parámetro al resto de los nodos del cluster, por lo que cada nodo debe lanzar mosctl setspeed en algún punto de la ejecución de los scripts de inicialización si el cluster tiene máquinas distintas y se quiere aprovechar el cluster al máximo. Actualmente en openMosix se emplea como unidad una diezmilésima de la potencia de cálculo de un Pentium-III a 1.4GHz. Esto es una unidad arbitraria, ya que la potencia depende también de la velocidad de memoria, de si el bus es de 33MHz o de 66MHz y de la tecnología de la memoria. Además, para algunas tareas un procesador de Intel es más rápido que uno de AMD, mientras que para otras el mismo procesador de AMD puede ser más rápido que el mismo procesador de Intel. Actualmente lo mejor que se puede hacer es estimar cuanto puede ser el procesador de cada nodo más lento o rápido que un Pentium-III a 1.4GHz para el tipo de tareas que se lancen en el cluster y después se asigna dicha potencia relativa de prueba para cada nodo, usando para ello el comando: mosctl setspeed valor donde valor: es la potencia computacional del procesador así calculada. Una vez que ya se tiene el cluster en pruebas ó en producción, siempre se puede ajustar el valor para que el cluster tenga el comportamiento que se quiere. En esta segunda etapa, por lo tanto, se ajuntan los valores: si se observa que un nodo esta demasiado cargado, le bajamos el factor de potencia de cómputo. Por otro lado, si se nota que un nodo suele estar desocupado mientras que los otros nodos trabajan demasiado, se puede subir su potencia computacional estimada con este comando. Es algo normal en openMosix jugar con la potencia computacional estimada del nodo para mejorar la respuesta del cluster al usuario. Para ello, se aumenta un 10% de forma artificial la potencia computacional estimada de los nodos sin monitor ni teclado, que sólo se dedican al cálculo, mientras se baja un 10% la potencia computacional estimada de los nodos con monitor y teclado en los que el usuario lanza tareas. Cuando se observe que algunos nodos en especial tengan ya problemas para responder a un usuario, se le baja un 20% la potencia computacional estimada. Modificando las estadísticas de carga El subsistema de migración automática de procesos necesita información sobre como evoluciona el comportamiento del cluster. Esta información con el tiempo se tiene que descartar, ya que lo que pasaba en el cluster hace varias horas no debería afectar al comportamiento actual del cluster. La información no se almacena de forma eterna. Se va acumulando de forma temporal, pero la importancia de los históricos de los sucesos va decreciendo según se van haciendo estas estadísticas más antiguas. El hecho de mantener la información de los históricos durante un tiempo permite que los picos de comportamiento anómalo en el uso del cluster no enmascaren el comportamiento real del cluster. Pero, por otro lado, la información debe desaparecer con el tiempo, para evitar que se tengan en cuenta sucesos que ocurrieron hace mucho tiempo, pero que ahora no tienen importancia. Se menciono como ajustar el tiempo que se mantenían las estadísticas de un proceso, ahora se mencionara como se ajusta el parámetro para un nodo en concreto. El uso de los recursos de un nodo en un cluster openMosix es una medida compuesta del uso de los recursos por los procesos que tienen un ritmo de decaída de las estadísticas lento y el uso de los recursos por los procesos que tienen un ritmo de decaídas rápido. La sintaxis de la instrucción que determina el cálculo de la medida será: 132 ANEXO 7 Optimizando el cluster mosctl setdecay intervalo procentajelento porcentajerápido Donde intervalo: será el intervalo en segundos entre recálculos de las estadísticas, porcentajelento: el tanto por mil de uso que se almacena originado por procesos con decaída lenta de estadísticas, Porcentajerápido: el tanto por mil que se almacena de procesos con decaída rápida de estadísticas. ejemplo: mosctl setdecay 60 900 205 Esto hace que las estadísticas históricas por nodo se recalculen cada 60 segundos. Se recalculan utilizando para acumular resultados como factor de ponderación un 90% para la carga de los procesos de decaída lenta de antes de los últimos 60 segundos, un 20.5% para la carga de los procesos de decaída rápida de antes de los últimos 60 segundos y la carga del sistema de los últimos 60 segundos sin ponderación. Esto permite hacer que las estadísticas por nodo evolucionen a más velocidad ó que sean las estadísticas más constantes en el tiempo -lo que mejora el aprovechamiento en clusters donde hay muchos procesos muy pequeños ejecutándose de forma aleatoria. Se puede obtener la información de los parámetros de permanencia de históricos en un cluster openMosix para un nodo particular con el comando mosctl y el modificador getdecay. La sintaxis del comando es: mosctl getdecay Programando openMosix Para programar openMosix a bajo nivel -es decir, tomando el control del cluster y de la migración- se pueden emplear tres mecanismos: Hacer uso de las herramientas de área de usuario. Este es el mecanismo recomendado para scripts en Perl ó para usar en shellscripts. Hacer uso del sistema de archivos /proc. En Linux se tiene un sistema de archivos virtual en /proc. Este sistema de archivos no existe físicamente en el disco y no ocupa espacio; pero los archivos y los directorios que en él se encuentran modelan distintos aspectos del sistema, tales como la memoria virtual de cada proceso, la red, las interrupciones ó la memoria del sistema, entre otras cosas. openMosix no puede ser menos y también se puede obtener información sobre su comportamiento y darle órdenes a través de /proc. Este método de operación es ideal en cualquier lenguaje que no tiene un método cómodo para llamar a procesos externos, pero permite acceder con facilidad a archivos, leyendo y escribiendo su contenido. Este es el caso de la práctica totalidad de los lenguajes de programación compilados. Hacer uso de la biblioteca de openMosix. El área de usuario de openMosix incluye una biblioteca en C que puede ser utilizada para hacer todo aquello que pueden hacer las herramientas de área de usuario. Este mecanismo sólo funciona en C, pero es el más cómodo para los programadores en este lenguaje. (miKel & Buytaert, 2004) 133 ANEXO 8 Descripción detallada Stress-Test ANEXO 8 Descripción detallada Stress-Test # distkeygen Esta aplicación es usada para generar 4000 pares de llaves RSA con una longitud de 1024 bits. Se distribuye en tantos procesos como procesadores haya en su cluster Openmosix vía fork. Requerimientos: Compilador gcc y la librería OpenSSL. (Hung, 2001). #portfolio Portfolio es un programa realizado en lenguaje Perl que simula distintos portfolios de acciones para un determinado período de tiempo. Está basado en el libro The intelligent asset Allocator de William Bernstein. Este programa está realizado bajo licencia GPL. (Nadeau, 2002). #eatmen Simplemente calcula funciones senoidales y raíces cuadradas para un valor determinado, lo hace un millón de veces, mientras escribe a un archivo el valor del contador del bucle (archivo que aumenta su tamaño enormemente). Este test es iniciado automáticamente tantas veces (en forma simultánea) según la cantidad de procesadores que haya en su cluster openMosix. #forkit Este test es similar al anterior pero en cambio usa la llamada a sistema fork() para crear múltiples procesos (tres veces el número de procesadores de su cluster. No escribe la salida a ningún archivo como lo hace eatmen. #mfstes Este programa crea un archivo de 10MB y lo copia hacia y desde todos los nodos. Es para chequear al oMFS. TM TM TM #test kernel syscall El Linux Test Project es un proyecto que nace de la unión de SGI , IBM , OSFL , y Bull con el objetivo de dar a la comunidad open source programas de testeo (test suites) para validar la confiabilidad, robustez y estabilidad de Linux. El Linux Test Project es una colección de herramientas para evaluar el kernel. El objetivo es mejorar el kernel. Los Interesados en contribuir son invitados a unirse a este proyecto. Más información en http://ltp.sf.net ó en http://ltp.sourceforge.net #moving El archivo moving.sh moverá a start_openMosix_test.sh a cada nodo en su cluster openMosix mientras este corriendo el test. Entonces 'start_openMosix_test.sh' migrará cada minuto hacia otro nodo durante la ejecución del mismo. Dependiendo de la duración del test en su cluster migrará de 20 a 40 veces. Instalación Desde las fuentes Ubicándose por ejemplo en /usr/local: gunzip ontest.tar.gz tar -xvf omtest.gz Después cd /usr/local/omtest y ejecute: ./compile_tests.sh Esto instalará los módulos y compilará los archivos necesarios. Necesitará privilegios de administrador para ello (rot). Pudiendo luego correr el openMosix stress-test como simple usuario (quizás deba ahora borrar los archivos temporales de la ejecución como administrador de /tmp porque no tendrá permiso de sobrescribirlos luego como simple usuario. Puede ejecutar el test con el siguiente comando: ./start_openMosix_test.sh Usando un paquete RPM Instálelo con el siguiente comando: rpm -ihv omtest.rpm Ahora puede iniciar el openMosix Stress-test con el siguiente comando: start_openMosix_test.sh (el paquete RPM será instalado en /usr/local/omtest) Download Version 0.1-4 del openMosix stress-test omtest-0.1-4.tar.gz (sources-package) omtest-0.1-4.i386.rpm (RPM-package) 134 ANEXO 8 Descripción detallada Stress-Test Cambios: -se incluyó un archivo con la versión version.txt -se actualizó ltp test-package -se agregó lmbench al stress-test. (debe ser ejecutado manualmente por run_lmbench.sh) Version 0.1-3 del openMosix stress-test omtest-0.1-3.tar.gz (sources-package) omtest-0.1-3.i386.rpm (RPM-package) Cambios: -stderr ahora también reporta hacia stdout después de cada test. -se corrigió un pequeño bug en kernel-syscall start-script (directorio tmp). -se corrigió un mensaje de error que se producíia durante el borrado de los archivos temporales (distkeygen test). -Usted puede ahora correr también el stress-test (solamente la instalación requiere privilegios de administrador) para openMosix como usuario común. Version 0.1-2 del openMosix stress-test omtest-0.1-2.tar.gz (sources-package) omtest-0.1-2.i386.rpm (RPM-package) Cambios: -stderr es copiado al informe generado por el test -se agregó un chequeo para nodos que son parte del cluster pero que estan sin funcionar. Version 0.1-1 of the openMosix stress-test omtest-0.1-1.tar.gz (sources-package) omtest-0.1-1.i386.rpm (RPM-package) Informe de Ejemplo Este es un ejemplo del informe generado por este test en un cluster openMosix versión 2.4.18-1 de 5 nodos openMosix-stress-test-report.txt (ejemplo) Descargo de responsabilidad Todos los fuentes de los programas son entregados sin garantías. Use el openMosix stress-test a su propio riesgo y siéntase libre de contribuir con sus propias ideas. El autor de este test para cluster no es responsable de ningún error y sus consecuencias mientras esté corriendo el stress-test en su sistema. Asegúrese de hacer una copia de respaldo antes de empezar con este test, debido a que quizás pueda sobrecargar y hasta colgar su sistema. (miKel & Buytaert, 2004). 135 ANEXO 9 abyss.pov ANEXO 9 abyss.pov // Persistence Of Vision raytracer version 3.5 sample file. //============================================ // The field, new improved version October. 2001 // Copyright Gilles Tran 2001 // http://www.oyonale.com //-------------------------------------------// Render with a 2.67 ratio such as 320*120, 640*240, 1024*384, 1280*480 //-------------------------------------------// -w320 -h120 // -w640 -h240 +a0.3 // -w1024 -h384 +a0.3 // Uncomment AreaOK=true below to turn on the area light // This will blur the shadow under the submarine // but the rendering time will extremely slow global_settings{max_trace_level 15} #declare AreaOK=false; //#declare AreaOK=true; #include "colors.inc" #include "functions.inc" //============================================ // General //============================================ //-------------------------------------------// Camera //-------------------------------------------#declare PdV=<-20, -20, -400>; camera{ location PdV direction z*2 up y right 8*x/3 look_at <-20, 30, 0> } //-------------------------------------------// reorientation macro //-------------------------------------------#macro mOrient(P1,P2) #local yV1=vnormalize(P2-P1); #local xV1=vnormalize(vcross(yV1,z)); #local zV1=vcross(xV1,yV1); matrix <xV1.x,xV1.y,xV1.z,yV1.x,yV1.y,yV1.z,zV1.x,zV1.y,zV1.z,P1.x,P1.y,P1.z> #end //-------------------------------------------// colors //-------------------------------------------#declare colWater1=rgb<0,79,159>/255; #declare colWater2=rgb<7,146,217>/255; #declare colWater3=rgb<82,239,238>/255; #declare colSub=<7/255,146/255,217/255>; //-------------------------------------------// lights //-------------------------------------------light_source {<-10, 1000, -10> color colWater2*10 #if (AreaOK) area_light x*200,z*200, 3,3 adaptive 1 jitter orient #end } light_source {<-200, -1000, -300> color colWater2*2 shadowless media_interaction off} light_source {PdV color colWater2*2 shadowless media_interaction off} //-------------------------------------------// mine textures //-------------------------------------------#declare txtMine=texture { pigment{color colWater3*0.1} 136 ANEXO 9 abyss.pov finish{ambient 0 diffuse 0.4 specular 0.03 roughness 0.2 reflection 0.05} } #declare txtCable=texture { pigment{color colWater3*0.1} finish{ambient 0 diffuse 0.1 specular 0.02 roughness 0.2} } //-------------------------------------------// sub textures //-------------------------------------------#declare txtSkin=texture{ pigment{ function{min(1,max(0,y))} turbulence 0.01 omega 1.5 lambda 5 poly_wave 1.5 color_map{[0 Clear][0.25 rgbt<0,0,0,0.7>] [0.4 rgbt<0,0,0,0.3>]} scale 38 translate -y*17 } finish{ambient 0 diffuse 0.6 specular 0.1 roughness 1/10} } #declare trb=0.0001; #declare pigLettre=pigment{bozo color_map{[0 White*1.3][1 White*0.5]}} #declare txtLettre=texture{ // submarine name pigment { object { text{ttf "cyrvetic.ttf" "PERSISTENCE" 10, 0.3*x translate -z*0.5 scale <1,1,10> } pigment{color Clear}, pigment{pigLettre} } rotate y*90 scale 1.5 translate <-10,-1,-25> } finish{ambient 0 diffuse 0.4} } #declare txtSub0=texture { pigment{rgb colSub*0.2} finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } // Thanks to Bob H. for the help regarding these textures #declare txtSubBase=texture { pigment { cells color_map { [.45 rgb <colSub.x*0.1,colSub.y*0.1,colSub.z*0.1>] [.55 rgb <colSub.x,colSub.y,colSub.z>*0.8] } scale <100,.125,1> } scale 3 finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } #declare txtSubTop= texture{txtSubBase} texture { pigment { cells color_map { [.25 rgbf <colSub.x*0.1,colSub.y*0.1,colSub.z*0.1,0>] [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] } scale <100,0.75,1> } scale 3.5 finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } 137 ANEXO 9 abyss.pov texture { pigment { cells color_map { [.25 rgbf <colSub.x*0.4,colSub.y*0.4,colSub.z*0.4,0>] [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] } scale <100,0.45,1> } scale 2.5 finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } texture{txtSkin} #declare txtSubBottom= texture{txtSubBase} texture { pigment { cells color_map { [.25 rgbf <colSub.x*0.5,colSub.y*0.5,colSub.z*0.5,0>] [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] } scale <100,.75,1> } scale 5 finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } texture { pigment { cells color_map { [0 rgbf <colSub.x*0.5,colSub.y*0.5,colSub.z*0.5,.5>] [1 rgbf <colSub.x,colSub.y,colSub.z,1>] } scale <100,0.25,1> } scale 5 translate 1 finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} } texture{txtLettre} texture{txtSkin} //============================================ // Mine //============================================ //-------------------------------------------// Spikes //-------------------------------------------#declare Spike = union{ #declare rSpike1=0.08; #declare rSpike2=rSpike1*0.3; #declare ySpike=0.4; cone{0,rSpike1,y*ySpike,rSpike2} sphere{0,rSpike2 translate y*ySpike} sphere{0,rSpike1*1.5 scale <1,0.3,1>} #declare i=0;#while (i<360) sphere{0,0.015 scale <2,1,2> translate <rSpike1*2.8,-0.04,0> rotate y*i} #declare i=i+30;#end translate y } //-------------------------------------------138 ANEXO 9 abyss.pov // Mine body //-------------------------------------------#declare rd=seed(0); #declare MineBody=union { isosurface { function{x*x+y*y+z*z-1 +f_noise3d(x*10,y*10,z*10)*0.05} max_gradient 2.492 contained_by{sphere{0,1}} } #declare i=0; #while (i<360) #declare j=0; #while (j<180) object{Spike rotate z*(i+rand(rd)*2) rotate y*(j+rand(rd)*2)} #declare j=j+45; #end #declare i=i+45; #end object{Spike rotate 90*y} object{Spike rotate -90*y} rotate 360*rand(rd) } //-------------------------------------------// Mine cable and decorative collar //-------------------------------------------#declare rFil=0.03; #declare yFil=100; #declare MineCable=isosurface{ function{f_helix1(x,y,z,3,35,0.35*rFil,0.55*rFil,2,1,0)} contained_by {box {<-rFil,0,-rFil>,<rFil,yFil,rFil>}} max_gradient 2.552 scale <1,-1,1>*3 translate -y } #declare MineCollar=lathe{ cubic_spline 15, <0.058,0.003>,<0.081,0.000>,<0.101,0.055>,<0.099,0.085>,<0.104,0.132>,<0.066,0.152>, <0.095,0.169>,<0.089,0.194>,<0.144,0.227>,<0.143,0.281>,<0.145,0.307>,<0.109,0.325>, <0.067,0.353>,<0.031,0.362>,<0.030,0.363> translate -y*0.363 } //-------------------------------------------// Mine //-------------------------------------------#declare Mine=union{ object{MineBody} sphere{0,1 scale <0.4,0.14,0.4> translate -y*0.91} #declare i=0;#while (i<360) cylinder{0,-y*0.1,0.02 translate <0.35,-0.91,0> rotate y*i} #declare i=i+30;#end object{MineCollar scale <1.2,2,1.2> translate -y*0.92} object{MineCollar translate -y*2} object{MineCable} texture{txtMine} } //============================================ // Submarine //============================================ #declare Sc=3; // general scaling parameter #declare SX=6*Sc; // x scaling #declare SYbot=10*Sc;// y scaling for the bottom #declare SYtop=2*Sc; // y scaling for the top #declare SZfront=20*Sc; // z scaling for the front #declare SZrear=100*Sc;// z scaling for the rear 139 ANEXO 9 abyss.pov //-------------------------------------------// Main parts //-------------------------------------------#declare Part1=blob{ // bottom front threshold 0.6 sphere{0,1,1} cylinder{-z*2,z,0.04,-1 translate <-0.2,-0.3,1> pigment{Black}} cylinder{-z*2,z,0.04,-1 translate <-0.17,-0.18,1> pigment{Black}} sphere{0,1,1 scale <0.1,0.45,1.05>} sphere{0,1,1 scale <0.3,0.45,0.8>} } #declare Part2=blob{ // top front threshold 0.6 sphere{0,1,1} sphere{0,1,1 scale <0.3,0.45,0.8>} sphere{0,1,1 scale <0.2,1.2,1.05>} } #declare Part3=blob{ // bottom rear threshold 0.6 sphere{0,1,1} cylinder{-x,0,1,1 scale <0.5,0.03,0.02> translate <0,-0.05,0.45>} cylinder{-y,0,1,1 scale <0.03,0.2,0.02> translate <0,-0.05,0.45>} } #declare Part4=blob{ // top rear threshold 0.6 sphere{0,1,1} cylinder{-y,y,2,2 scale <0.03,0.3,0.012> translate <0,0.5,0.45>} sphere{0,1,1 scale <0.2,1.2,0.4>} } cylinder{-x,0,1,1 scale <0.2,0.2,0.04> rotate x*-10 translate <0,1.5,0.2>} cylinder{0,y,0.2,2 scale <0.6,2.5,0.4>*0.7 translate <0,-0.05,0.16>} cylinder{0,y,0.2,2 scale <0.4,2.5,0.4>*0.7 translate <0,-0.05,0.165>} cylinder{0,y,0.2,2 scale <0.2,2.5,0.4>*0.7 translate <0,-0.05,0.17>} //-------------------------------------------// Top //-------------------------------------------#declare HalfSubTop=union{ difference{ object{Part2} // top front plane{y,0} plane{z,0 inverse} plane{x,0 inverse} scale <SX,SYtop,SZfront> } difference{ object{Part4} // top rear plane{y,0} plane{z,0} plane{x,0 inverse} scale <SX,SYtop,SZrear> } } #declare SubTop=union{ object{HalfSubTop} object{HalfSubTop scale <-1,1,1>} texture{txtSubTop} } //-------------------------------------------// Bottom //-------------------------------------------#declare HalfSubBottom=union{ difference{ object{Part1} // bottom front plane{y,0 inverse} plane{z,0 inverse} plane{x,0 inverse} scale <SX,SYbot,SZfront> } difference{ object{Part3} // bottom rear plane{y,0 inverse} 140 ANEXO 9 abyss.pov plane{z,0} plane{x,0 inverse} scale <SX,SYbot,SZrear> } } #declare SubBottom=union{ object{HalfSubBottom} object{HalfSubBottom scale <-1,1,1>} texture{txtSubBottom} } //-------------------------------------------// Decorative elements //-------------------------------------------#declare Balustrade=union{ #declare rB1=0.02; #declare rB2=0.04; #declare yB=1; #declare rB3=yB*6; #declare rB4=3; #declare zB=20; #declare zB2=8; #declare i=0; #while (i<zB) cylinder{0,y*yB,rB1 translate z*i} #declare i=i+zB/12; #end cylinder{0,z*zB,rB2 translate y*yB} cylinder{0,z*zB,rB2 translate y*yB*0.3} cylinder{0,z*zB,rB2 translate y*yB*0.6} union{ difference{torus{rB3,rB2 rotate z*90} plane{y,0} plane{z,0 inverse} plane{z,0 rotate x*-45}} cylinder{0,-z*zB*0.1,rB2 translate y*rB3 rotate x*-45} translate y*(yB-rB3) } union{ difference{torus{rB4,rB2} plane{x,0 inverse} translate <0,yB,0>} difference{torus{rB4,rB1} plane{x,0 inverse} translate <0,yB*0.5,0>} #while (i<180) cylinder{0,y*yB,rB1 translate -z*rB4 rotate y*i} #declare i=i+180/14; #end scale <0.4,1,1> translate z*(rB4+zB) } union{ difference{torus{rB3,rB2 rotate z*90} plane{y,0} plane{z,0 inverse} plane{z,0 rotate x*-65}} cylinder{0,-z*zB*0.1,rB2 translate y*rB3 rotate x*-65} translate y*(yB-rB3) scale <1,1,-1> translate z*(zB+rB4*2) } } //-------------------------------------------// guns //-------------------------------------------#declare Guns0=union{ superellipsoid{<0.3,0.3> translate z scale <0.8,1,4>} union{ cone{0,0.4,z*12,0.3} union{ cone{0,0.3,z*1.5,0.5} difference{ sphere{0,0.5} cylinder{-z,z,0.3} translate z*1.5 } translate z*12 141 ANEXO 9 abyss.pov } translate z*8 } } translate -z*3 #declare Wheel=blob{ threshold 0.6 sphere{0,1.3,1 scale <1,1.2,1>} cylinder{0,-y*3,0.8,1} #declare Teta=0; #while (Teta<360) cylinder{0,x*3.4,0.4,1 rotate y*Teta} cylinder{0,y,0.4,1 translate x*3 rotate y*Teta} sphere{0,0.6,1 translate x*3 rotate y*Teta} sphere{0,0.4,1 translate x*3 rotate y*(Teta+6)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+12)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+18)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+24)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+30)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+36)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+42)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+48)} sphere{0,0.4,1 translate x*3 rotate y*(Teta+54)} sphere{0,0.5,1 translate x*3 rotate y*(Teta+60)} sphere{0,0.5,1 translate x*3 rotate y*(Teta+66)} #declare Teta=Teta+72; #end } #declare Guns1=union{ object{Guns0} object{Wheel rotate y*10 scale 0.7 rotate z*90 translate -x*1.5} } #declare Eye=union{ torus{4.5,0.5} difference{ sphere{0,4.3} box{-5,5 scale <1,1,0.05>} box{-5,5 scale <1,1,0.05> translate z} box{-5,5 scale <1,1,0.05> translate z*2} box{-5,5 scale <1,1,0.05> translate z*3} box{-5,5 scale <1,1,0.05> translate z*4} box{-5,5 scale <1,1,0.05> translate -z} box{-5,5 scale <1,1,0.05> translate -z*2} box{-5,5 scale <1,1,0.05> translate -z*3} box{-5,5 scale <1,1,0.05> translate -z*4} scale <1,0.7,1> } } #declare Ring1=union{ cylinder{-0.2*x,0.2*x,1.2} torus{1.1,0.1 rotate z*90 scale <2,1,1> translate -x*0.2} torus{1.1,0.1 rotate z*90 scale <2,1,1> translate x*0.2} } #declare Elbow1=intersection{torus{2,1} plane{z,0 inverse} plane{x,0 inverse} } #declare Thingie=union{ torus{1.5,0.3 rotate z*90 translate -x} cylinder{-x,x,1.5} superellipsoid{<0.2,0.2> scale <1.5,2,2.5> translate x*2.5} object{Eye scale 1.5/7 rotate -x*90 translate <2.5,0,-2.5>} object{Eye scale 1.5/7 rotate -x*90 translate <2.5,0,-2.5> scale <1,1,-1>} sphere{0,1.5 scale <0.5,1,1> translate x*4} sphere{0,1.5 scale <0.5,1,1> translate x*16} cylinder{x*4,x*16,1.2} torus{1.9,0.1 rotate z*90 translate x*16.5} cylinder{x*16.5,x*17.5,2} torus{1.9,0.1 rotate z*90 translate x*17.5} cylinder{x*17.5,x*23,1.5} union{ torus{0.5,0.1} 142 ANEXO 9 abyss.pov intersection{torus{2.5,0.5 rotate x*90} plane{y,0 inverse} plane{x,0} translate x*2.5} torus{0.5,0.1 translate -x*2.5 rotate z*-30 translate x*2.5 } torus{0.5,0.1 translate -x*2.5 rotate z*-60 translate x*2.5 } torus{0.5,0.1 translate -x*2.5 rotate z*-90 translate x*2.5 } union{ cylinder{0,9*x,0.5} cylinder{2*x,5*x,0.7} torus{0.5,0.2 rotate z*90 translate x*2} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.3} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.6} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.9} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.2} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.5} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.8} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.1} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.4} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.7} torus{0.5,0.2 rotate z*90 translate x*5} torus{0.5,0.3 rotate z*90 translate x*8} cone{0,0.7,x,0.9 translate x*8} torus{0.9,0.2 rotate z*90 translate x*9} translate <2.5,2.5,0> } translate <2.5,2,1.7> } union{ torus{0.5,0.1} intersection{torus{2.5,0.5 rotate x*90} plane{y,0 inverse} plane{x,0} translate x*2.5} torus{0.5,0.1 translate -x*2.5 rotate z*-30 translate x*2.5 } torus{0.5,0.1 translate -x*2.5 rotate z*-60 translate x*2.5 } torus{0.5,0.1 translate -x*2.5 rotate z*-90 translate x*2.5 } union{ cylinder{0,9*x,0.5} cylinder{3*x,6*x,0.7} torus{0.5,0.2 rotate z*90 translate x*3} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.3} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.6} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.9} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.2} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.5} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.8} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.1} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.4} torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.7} torus{0.5,0.2 rotate z*90 translate x*6} torus{0.5,0.3 rotate z*90 translate x*8} cone{0,0.7,x,0.9 translate x*8} torus{0.9,0.2 rotate z*90 translate x*9} translate <2.5,2.5,0> } translate <2.5,2,-1.7> } union{ superellipsoid{<0.2,0.2> scale <1,1.3,2.6>} object{Eye scale 1/7 rotate -x*90 translate z*-2.6} object{Eye scale 1/7 rotate -x*90 translate z*2.6} object{Eye scale 1/7 rotate y*90 translate <0,1.3,1.7>} object{Eye scale 1/7 rotate y*90 translate <0,1.3,-1.7>} cylinder{x,x*3,1} torus{1,0.2 rotate z*90 translate x*3} intersection{torus{4.5,1 rotate x*90} plane{y,0 inverse} plane{x,0 inverse} scale <0.5,1,1> translate <3,-4.5,0>} torus{1,0.3 scale <0.5,4,1> translate <3+2.25,-3,0>} translate <15,4.5,0> } #declare Teta=0; #while (Teta<360) union{ box{<0,-0.1,-0.05>,<12,0.1,0.05> translate <4,1.2,0>} cylinder{-x,2*x,0.1 translate y*1.5} sphere{0,0.2 translate <20,1.5,0>} sphere{0,0.1 translate <16.8,2,0>} 143 ANEXO 9 abyss.pov sphere{0,0.1 translate <17.2,2,0> rotate x*10} cylinder{x*20,x*23,0.18 translate y*1.5} rotate x*Teta } #declare Teta=Teta+20; #end translate x } #declare GunSupport=union{ superellipsoid{<0.6,0.6> translate y scale <0.3,3,1> translate -z*2} union{ union{ superellipsoid{<0.7,0.7> translate y scale <1.5,3.8,1>} #declare i=0; #while (i<6) sphere{0,0.2 translate <-1,i+0.5,0.8>} sphere{0,0.2 translate <0,i+0.1,1>} sphere{0,0.2 translate <1,i+0.5,0.8>} #declare i=i+0.7; #end rotate -x*10 translate z*0.6 } cylinder{y*4,y*9,0.6} sphere{0,1 scale <4,1,4>} } } #declare Guns=union{ union{ object{Thingie rotate y*180 scale 0.5 rotate y*-90 rotate z*45 translate <0,4,5>} superellipsoid{<0.6,0.6> translate -z scale <0.6,1,3> translate -x*0.5} object{Guns1 translate -x*1.7} object{Guns1 translate -x*1.7 scale <-1,1,1>} rotate x*-20 translate y*10 } object{GunSupport} } #declare GunsBack=union{ union{ object{Thingie rotate y*180 scale 0.5 rotate y*-90 rotate z*45 translate <0,4,5>} superellipsoid{<0.6,0.6> translate -z scale <0.6,1,3> translate -x*0.5} object{Guns1 translate -x*1.7} object{Guns1 translate -x*1.7 scale <-1,1,1>} rotate x*-5 translate y*10 } object{GunSupport} } //-------------------------------------------// snorkels and vertical thingies //-------------------------------------------#declare Snorkel1=union{ cone{0,0.3,y*2,0.25} cone{y*2,0.25,y*3,0.1} union{ difference{sphere{0,1 scale<0.3,0.2,0.3>}plane{y,0 inverse}} difference{sphere{0,1 scale<0.3,0.6,0.3>}plane{y,0}} translate y*3 } scale <0.8,1,0.8> } #declare Snorkel2=blob{ threshold 0.6 cylinder{-y,y*4,0.2,1} sphere{0,0.4,1 scale <1,1,2> translate y*3.5} sphere{0,0.3,1 scale <3,1,1> translate y*2.5} scale <0.8,1,0.8> } #declare Snorkel3=union{ blob{ 144 ANEXO 9 abyss.pov threshold 0.6 cylinder{0,y*3.4,0.25,1 scale <1,1,3>} cylinder{0,y*5,0.03,1 translate <0,0,-0.5>} } union{ cylinder{0,y*4,0.03} sphere{0,0.1 translate y*4} translate <-0.1,0,0.5> } scale <0.8,1,0.8> } //-------------------------------------------// lots of decorative stuff //-------------------------------------------#declare nDeco=13; #declare Deco=array[nDeco] #declare Deco[0]=union{ cylinder{0,y*2,0.2} torus{1,0.2 rotate x*90 translate y*3} scale 0.5 } #declare Deco[1]=cone{-y*0.5,0.2,y*4,0.1} #declare Deco[2]=blob{ threshold 0.6 cylinder{-x,x,0.25,1 scale <1,1,2>} cylinder{0,-y,0.21,1 translate -x*0.8} cylinder{0,-y,0.21,1 translate x*0.8} translate y*0.7 scale 1 } #declare Deco[3]=object{Deco[2] rotate y*90} #declare Deco[4]=torus{1,0.2 rotate z*90} #declare Deco[5]=object{Deco[3] rotate y*90 scale <1,1.4,1>} #declare Deco[6]=union{ cylinder{0,y*0.4,0.1} sphere{0,1 scale <0.1,0.1,0.5> translate y*0.4} } #declare Deco[7]=difference{sphere{0,1} cylinder{-z,0,0.8} scale <2,0.5,2>translate -y*0.2} #declare Deco[8]=difference{sphere{0,1} cylinder{-z,0,0.9} scale <2,0.5,4>translate -y*0.2} #declare Deco[9]=cone{0,0.08,y*2,0.03 scale <1,1,2>} #declare Deco[10]=sphere{0,1 scale <0.2,0.1,0.4>} #declare Deco[11]=object{Deco[4] scale 1.2} #declare Deco[12]=object{Deco[5] scale 1.3} #declare Ladder=union{ #declare i=0; #while (i<9) object{Deco[3] scale 0.8 rotate z*90 translate y*i*0.8} #declare i=i+1; #end } #declare Decos=union{ #declare rd=seed(4); #declare Start0=-40; #declare End0=40; #declare nstep=200; #declare i=0; #declare k=0; #while (i<1) #declare j=i; #declare Start=<-rand(rd)*5*(mod(k,2)*2-1),1,(1-j)*Start0+j*End0>; #declare Dir=y; #declare Norm1=<0,0,0>; #declare Inter=trace( SubTop, Start, Dir, Norm1); #if (vlength(Norm1)!=0) #if (vlength(vcross(Norm1,y))<0.9) #declare n=int(rand(rd)*nDeco); object{Deco[n] scale 0.4 mOrient(Inter,Inter+Norm1)} #end #end #declare k=k+1; #declare i=i+1/nstep; 145 ANEXO 9 abyss.pov #end } #declare Submarine=union{ union{ object{SubTop} object{Decos texture{txtSubTop}} object{Ladder translate <-1.5,4,40>} object{Ladder translate <1.5,4,40>} object{Guns rotate y*180 scale 0.3 translate <0,4,30>} object{GunsBack scale 0.3 translate <0,4,70>} union{ object{Snorkel1 translate z*3} object{Snorkel2} object{Snorkel3 translate -z*2} scale 2*<1,1.1,1> translate <0,10,50> } object{Balustrade scale 2.5 translate <-4,2,5>} object{Balustrade scale 2.5 translate <-4,2,5> scale <-1,1,1>} union{ object{Balustrade scale 2 translate <-3,2,5>} object{Balustrade scale 2 translate <-3,2,5> scale <-1,1,1>} rotate y*180 translate z*100 } texture{txtSub0} scale <1,1.3,1> } object{SubBottom} } //============================================ // Final //============================================ #declare posSub=<19,5,0>; #declare rotSub=-15; //-------------------------------------------// mines //-------------------------------------------union{ light_group{ object{Mine rotate y*80 scale 14 } light_source{<-10,-20,-40> color rgb -4 shadowless} // negative light !!! translate <-110, 41, -205> global_lights on } light_group{ object{Mine rotate -y*10 scale 8 } light_source{<-10,-20,-40> color rgb -2 shadowless} translate <-75, 25, -165> global_lights on } object{Mine rotate y*125 scale 5 translate <105, -5, -155>} translate y*-8 } union{ #declare rd=seed(0); #declare i=0; #while (i<20) object{Mine rotate y*125 scale 3 translate <50+rand(rd)*(200+i*10),(0.5rand(rd))*60,i*30>} object{Mine rotate y*150 scale 3 translate <-50-rand(rd)*(200+i*10),(0.5rand(rd))*60,i*30>} object{Mine rotate y*10 scale 3 translate <50+rand(rd)*(200+i*10),(0.5rand(rd))*140+50+i*10,i*30>} object{Mine rotate y*37 scale 3 translate <-50-rand(rd)*(200+i*10),(0.5rand(rd))*140+50+i*10,i*30>} 146 ANEXO 9 abyss.pov #declare i=i+1; #end rotate y*rotSub translate posSub translate -z*150 translate x*30 } //-------------------------------------------// submarine and media //-------------------------------------------union{ object{Submarine scale 3/4 translate z*-10 translate y*10} sphere{0,1 scale 410 hollow texture{pigment{Clear}finish{ambient 0 diffuse 0}} interior{ media{ scattering {5,0.00034 eccentricity 0.7 extinction 0.8} absorption <255-23,255-171,255-239>*0.0005/255 intervals 3 method 3 } } } scale 4 rotate y*rotSub translate posSub } 147 ANEXO 10 chess2.pov ANEXO 10 chess2.pov // // // // // // // // // // // // // Persistence Of Vision raytracer version 3.5 sample file. POV-Ray scene description for chess board. By Ville Saari Copyright (c) 1991 Ferry Island Pixelboys This scene has 430 primitives in objects and 41 in bounding shapes and it takes over 40 hours to render by standard amiga. If you do some nice modifications or additions to this file, please send me a copy. My Internet address is: [email protected] -w320 -h240 -w800 -h600 +a0.3 // Note : CHESS2.POV was created from Ville Saari's chess.pov // -- Dan Farmer 1996 // - Cchanged textures // - Added camera blur and changed focal length // - Use sky sphere // - Modularized the code // - Added felt pads to bottom of pieces // remaining manual bounding commented out by Bob Hughes, August 31, 2001 global_settings { assumed_gamma 2.2 max_trace_level 5 } #include #include #include #include #include #include "shapes.inc" "colors.inc" "textures.inc" "skies.inc" "metals.inc" "woods.inc" #declare #declare #declare #declare FB_Quality_Off FB_Quality_Fast FB_Quality_Default FB_Quality_High = = = = 0; 1; 2; 3; #declare FB_Quality= FB_Quality_High; camera { location <59, 20, -55> direction <0, 0, 2> up <0, 1, 0> right <4/3, 0, 0> look_at <0, -1, 1> #if(FB_Quality != FB_Quality_Off) aperture 2.25 focal_point <0, 0, 0> #end #switch(FB_Quality) #case(FB_Quality_Off) aperture 0 #debug "\nNo focal blur used...\n" #break #case (FB_Quality_Fast) blur_samples 7 confidence 0.5 // default is 0.9 variance 1/64 // default is 1/128 (0.0078125) #debug "\nFast focal blur used...\n" #break #case(FB_Quality_Default) blur_samples 19 confidence 0.90 // default is 0.9 variance 1/128 // default is 1/128 (0.0078125) #debug "\nDefault focal blur used...\n" #break #case(FB_Quality_High) 148 ANEXO 10 chess2.pov blur_samples 37 confidence 0.975 // default is 0.9 variance 1/255 // default is 1/128 (0.0078125) #debug "\nHigh Quality focal blur used...\n" #break #else #debug "\nNo focal blur used...\n" #end } light_source { <800, 600, -200> colour White } #declare PawnBase = union { intersection { sphere { <0, 0, 0>, 2.5 } plane { -y, 0 } } cylinder { 0, y*0.35, 2.5 pigment { green 0.65 } } } #declare PieceBase = union { intersection { sphere { <0, 0, 0>, 3 } plane { -y, 0 } } cylinder { 0, y*0.35, 3.0 pigment { green 0.65 } } } #declare Pawn = union { sphere { <0, 7, 0>, 1.5 } sphere { <0, 0, 0>, 1 scale <1.2, 0.3, 1.2> translate 5.5*y } intersection { plane { y, 5.5 } object { Hyperboloid_Y translate 5*y scale <0.5, 1, 0.5> } plane { -y, -2.5 } } sphere { <0, 0, 0>, 1 scale <2, 0.5, 2> translate <0, 2.3, 0> } object { PawnBase } } #declare Rook = union { intersection { union { plane { +x, -0.5 } plane { -x, -0.5 } plane { y, 9 } } union { plane { +z, -0.5 } plane { -z, -0.5 } plane { y, 9 } } plane { y, 10 } object { Cylinder_Y scale <2, 1, 2> } object { Cylinder_Y scale <1.2, 1, 1.2> inverse } plane { -y, -8 } 149 ANEXO 10 chess2.pov } intersection { plane { y, 8 } object { Hyperboloid_Y scale <1, 1.5, 1> translate 5.401924*y } plane { -y, -3 } } sphere { <0, 0, 0>, 1 scale <2.5, 0.5, 2.5> translate 2.8*y } object { PieceBase } } #declare Knight = union { intersection { object { Cylinder_Z scale <17.875, 17.875, 1> translate <-18.625, 7, 0> inverse } object { Cylinder_Z scale <17.875, 17.875, 1> translate <18.625, 7, 0> inverse } object { Cylinder_X scale <1, 5.1, 5.1> translate <0, 11.2, -5> inverse } union { plane { y, 0 rotate 30*x translate 9.15*y } plane { z, 0 rotate -20*x translate 10*y } } union { plane { -y, 0 rotate 30*x translate 7.15*y } plane { y, 0 rotate 60*x translate 7.3*y } } union { plane { y, 0 rotate -45*z } plane { y, 0 rotate 45*z } translate 9*y } } object { Cylinder_Y scale <2, 1, 2> } sphere { <0, 7, 0>, 4 } 150 ANEXO 10 chess2.pov sphere { <0, 0, 0>, 1 scale <2.5, 0.5, 2.5> translate <0, 2.8, 0> } object { PieceBase } } #declare Bishop = union { sphere { <0, 10.8, 0>, 0.4 } intersection { union { plane { -z, -0.25 } plane { +z, -0.25 } plane { y, 0 } rotate 30*x translate 8.5*y } sphere { <0, 0, 0>, 1 scale <1.4, 2.1, 1.4> translate 8.4*y } } plane { -y, -7 } sphere { <0, 0, 0>, 1 scale <1.5, 0.4, 1.5> translate 7*y } intersection { plane { y, 7 } object { Hyperboloid_Y scale <0.6, 1.4, 0.6> translate 7*y } plane { -y, -3 } } sphere { <0, 0, 0>, 1 scale <2.5, 0.5, 2.5> translate 2.8*y } object { PieceBase } } #declare QueenAndKing = union { sphere { <0, 10.5, 0>, 1.5 } intersection { union { sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { inverse } <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, <1.75, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 rotate rotate rotate rotate rotate } rotate rotate rotate rotate rotate rotate 150*y } 120*y } 90*y } 60*y } 30*y } -30*y } -60*y } -90*y } -120*y } -150*y } 180*y } plane { y, 11.5 } 151 ANEXO 10 chess2.pov object { QCone_Y scale <1, 3, 1> translate 5*y } } plane { -y, -8 } sphere { <0, 0, 0>, 1 scale <1.8, 0.4, 1.8> translate 8*y } intersection { plane { y, 8 } object { Hyperboloid_Y scale <0.7, 1.6, 0.7> translate 7*y } plane { -y, -3 } } sphere { <0, 0, 0>, 1 scale <2.5, 0.5, 2.5> translate 2.8*y } object { PieceBase } } #declare Queen = union { sphere { <0, 12.3, 0>, 0.4 } object { QueenAndKing } } #declare King = union { intersection { union { intersection { plane { y, 13 } plane { -y, -12.5 } } intersection { plane { +x, 0.25 } plane { -x, 0.25 } } } plane plane plane plane plane plane { { { { { { +z, -z, +x, -x, +y, -y, 0.25 } 0.25 } 0.75 } 0.75 } 13.5 } -11.5 } } object { QueenAndKing } } #declare WWood = texture { T_Silver_3B } #declare BWood = texture { T_Gold_3C } #declare WPawn = object { Pawn // bounded_by { sphere { <0, 4, 0>, 4.72 } } texture { 152 ANEXO 10 chess2.pov } WWood pigment { quick_color red 0.95 green 0.62 } } #declare BPawn = object { Pawn // bounded_by { sphere { <0, 4, 0>, 4.72 } } } texture { BWood pigment { quick_color red 0.4 green 0.2 } } #declare WRook = object { Rook // bounded_by { sphere { <0, 5, 0>, 5.831 } } texture { WWood pigment { quick_color red 0.95 green 0.62 } } } #declare BRook = object { Rook // bounded_by { sphere { <0, 5, 0>, 5.831 } } texture { BWood pigment { quick_color red 0.4 green 0.2 } } } #declare WKnight = object { Knight // bounded_by { sphere { <0, 5, 0>, 5.831 } } texture { WWood pigment { quick_color red 0.95 green 0.62 } } } #declare BKnight = object { Knight rotate 180*y // bounded_by { sphere { <0, 5, 0>, 5.831 } } texture { BWood pigment { quick_color red 0.4 green 0.2 } } } #declare WBishop = object { Bishop // bounded_by { sphere { <0, 5.5, 0>, 6.265 } } texture { WWood pigment { quick_color red 0.95 green 0.62 } } } #declare BBishop = object { Bishop 153 ANEXO 10 chess2.pov rotate 180*y // bounded_by { sphere { <0, 5.5 ,0>, 6.265 } } texture { BWood pigment { quick_color red 0.4 green 0.2 } } } #declare WQueen = object { Queen /* bounded_by { intersection { sphere { <0, 6, 0>, 6.71 } object { Cylinder_Y scale <3, 1, 3> } } } */ texture { WWood pigment { quick_color red 0.95 green 0.62 } } } #declare BQueen = object { Queen /* bounded_by { intersection { sphere { <0, 6, 0>, 6.71 } object { Cylinder_Y scale <3, 1, 3> } } } */ texture { BWood pigment { quick_color red 0.4 green 0.2 } } } #declare WKing = object { King /* bounded_by { intersection { sphere { <0, 6.5, 0>, 7.16 } object { Cylinder_Y scale <3, 1, 3> } } } */ texture { WWood pigment { quick_color red 0.95 green 0.62 } } } #declare BKing = object { King /* bounded_by { intersection { sphere { <0, 6.5, 0>, 7.16 } object { Cylinder_Y scale <3, 1, 3> } } } */ texture { BWood pigment { quick_color red 0.4 green 0.2 } } } 154 ANEXO 10 chess2.pov /* Sky */ #declare SkySphere = sky_sphere { S_Cloud1 } /* Ground */ #declare Ground = plane { y, -80 pigment { green 0.65 } finish { ambient 0.25 diffuse 0.5 } } #declare FarSide = union { object { BPawn translate object { BPawn translate object { BPawn translate object { BPawn translate object { BPawn translate object { BPawn translate object { BPawn translate object { BPawn translate object object object object object object object object { { { { { { { { BRook BKnight BBishop BQueen BKing BBishop BKnight BRook <-28, <-20, <-12, < -4, < 4, < 12, < 20, < 28, translate translate translate translate translate translate translate translate 0, 0, 0, 0, 0, 0, 0, 0, <-28, <-20, <-12, < -4, < 4, < 12, < 20, < 28, 20> 20> 20> 20> 20> 20> 20> 20> 0, 0, 0, 0, 0, 0, 0, 0, } } } } } } } } 28> 28> 28> 28> 28> 28> 28> 28> } } } } } } } } /* bounded_by { object { Cylinder_X scale <1, 9.56, 9.56> translate <0, 6.5, 24> } } */ } #declare NearSide union { object { WPawn object { WPawn object { WPawn object { WPawn object { WPawn object { WPawn object { WPawn object { WPawn object object object object object object object object { { { { { { { { = translate translate translate translate translate translate translate translate WRook WKnight WBishop WQueen WKing WBishop WKnight WRook <-28, <-20, <-12, < -4, < 4, < 12, < 20, < 28, translate translate translate translate translate translate translate translate 0, 0, 0, 0, 0, 0, 0, 0, <-28, <-20, <-12, < -4, < 4, < 12, < 20, < 28, -20> -20> -20> -20> -20> -20> -20> -20> 0, 0, 0, 0, 0, 0, 0, 0, } } } } } } } } -28> -28> -28> -28> -28> -28> -28> -28> } } } } } } } } } #declare Pieces = union { object { NearSide } object { FarSide } /* bounded_by { intersection { plane { y, 13.5 } 155 ANEXO 10 chess2.pov sphere { -30*y, 63 } } } */ } #declare FramePiece = intersection { plane { +y, -0.15 } plane { -y, 3 } plane { -z, 35 } plane { <-1, 0, 1>, 0 } plane { < 1, 0, 1>, 0 } } // 45 degree bevel // 45 degree bevel #declare Frame = union { union { object { FramePiece } object { FramePiece rotate 180*y } texture { T_Wood20 scale 2 rotate y*87 translate x*1 finish { specular 1 roughness 0.02 ambient 0.35 } } } union { object { FramePiece rotate -90*y } object { FramePiece rotate 90*y } texture { T_Wood20 scale 2 rotate y*2 finish { specular 1 roughness 0.02 ambient 0.35 } } } } #declare Board = box { <-32, -1, -32> <32, 0, 32> texture { tiles { texture { pigment { //marble wrinkles turbulence 1.0 colour_map { [0.0 0.7 colour White colour White] [0.7 0.9 colour White colour red 0.8 green 0.8 blue 0.8] [0.9 1.0 colour red 0.8 green 0.8 blue 0.8 colour red 0.5 green 0.5 blue 0.5] } scale <0.6, 1, 0.6> rotate -30*y } finish { specular 1 roughness 0.02 reflection 0.25 } } // texture 156 ANEXO 10 chess2.pov tile2 texture { pigment { granite scale <0.3, 1, 0.3> colour_map { [0 1 colour Black colour red 0.5 green 0.5 blue 0.5] } } finish { specular 1 roughness 0.02 reflection 0.25 } } } // texture scale <8, 1, 8> } //texture } // intersection /* Table */ #declare Table = union { intersection { plane { +y, -3 } plane { -y, 8 } sphere { <0, -5.5, 0>, 55 } } intersection { plane { y, -8 } object { Hyperboloid_Y scale <10, 20, 10> translate -20*y } } pigment { granite scale 6 } finish { specular 1 roughness 0.02 reflection 0.3 } } object { Pieces } object { Board } object { Frame } object { Ground } object { Table } sky_sphere { SkySphere } 157 ANEXO 11 grenadine.pov ANEXO 11 grenadine.pov // // // // // // // // // // Persistence of Vision Ray Tracer Scene Description File File: grenadine.pov Vers: 3.5 Desc: Glass with liquid Date: 1999/06/04 Update: 2001/07/26, to work with POV-Ray 3.5 Auth: Ingo Janssen -w320 -h240 -w800 -h600 +a0.3 #version 3.5; #include "glass.inc" #include "lemon.inc" global_settings { assumed_gamma 1.0 max_trace_level 5 photons { spacing 0.01 // higher value 'lower' quality, faster parsing. autostop 0 jitter 0.5 max_trace_level 15 } } light_source { <500, 550, -100> rgb <1, 1, 1> spotlight radius 1 falloff 1.1 tightness 1 point_at <-19,-4,7> } camera { location look_at } <-0.5, 2.5, -7.0> <-0.5, 0.5, 0.0> sky_sphere { pigment { gradient y color_map { [0.0 rgb <0.2,0,1>] [1.0 color rgb 1] } } } union { //plane & background difference { box {<-20,-1,0>,<20,13,13>} cylinder{<-21,13,0>,<21,13,0>,13} } plane {y, 0} translate <0,-1.9999,7> pigment {rgb .5} finish {diffuse .5 ambient 0} } //====== The Glass ====== #declare Ri=0.95; #declare Glass= merge { difference { cylinder { -y*2,y*2,1 } sphere {-y*0.8,Ri} cylinder { -y*0.8,y*2.01,Ri} sphere {-y*1.9,0.1} } 158 ANEXO 11 grenadine.pov torus {0.975, 0.026 translate <0,2,0>} texture {T_Glass1} interior {ior 1.5} } //====== The bubbles and the juce ====== #declare Bubble= difference { sphere {0,0.1} sphere {0,0.09999999} } #declare S= seed(7); #declare I=0; #declare Bubbles= intersection { union { #while (I<60) object { Bubble scale rand(S) scale <1,0.7,1> translate <1,0.6,0> rotate <0,360*rand(S),0> } object { Bubble scale rand(S)*0.5 translate <rand(S),0.58,0> rotate <0,360*rand(S),0> } #declare I=I+1; #end //while } cylinder{y*0.5,y*0.85,Ri+0.00000001} } #declare Liquid= merge { sphere {-y*0.8,Ri+0.00000001} cylinder {-y*0.8,y*0.6,Ri+0.00000001} object {Bubbles} pigment {rgbf <0.9, 0.1, 0.2, 0.95>} finish {reflection 0.3} interior{ior 1.2} } //====== The glass and juice ===== union { object {Glass} object {Liquid} photons { target refraction on reflection on collect off } } object { LemonSlice scale <0.8,0.8,1> translate <-0.99,0,0> rotate <0,-30,0> translate <0,2,0> photons { pass_through } } 159 ANEXO 12 landscape.pov ANEXO 12 landscape.pov // // // // // // // // // // // // // // Persistence Of Vision Ray Tracer Scene Description File File: landscape.pov Vers: 3.5 Desc: Use of 'trace' for placing objects on isosurfaces/heightfields Furthermore showing the following techniques: - use of piment functions for creatig isosurface terrain - use function image type for heightfields - slope pattern - random variation of objects using rand() and macros - nested #while loops for placing objects in a grid - creation of simple trees using partly transparent textures Date: June 2001 Auth: Christoph Hormann // -w320 -h240 // -w512 -h384 +a0.3 #version 3.5; #declare Test_Render=false; #declare use_iso=false; #declare Viewpoint=1; // use simplified trees if true // use an isosurface object (HF with function image type otherwise) global_settings { assumed_gamma 1 max_trace_level 25 noise_generator 2 } #if (Viewpoint=1) camera { //location <3.7, -0.55, 0.3> location <3.0, 2.3, 0.3> direction y sky z up z right (4/3)*x look_at <0.0, 0.0, 0.1> angle 32 } #else camera { location <7, 14, 7> direction y sky z up z right (4/3)*x look_at <0.0, 0.0, 0.0> angle 32 } #end light_source { <1.0, 4.0, 1.3>*100000 color rgb <1.5, 1.4, 1.1> } // -------- Sky ------------sphere { 0,1 texture { pigment { gradient z color_map { [0.03 color rgb <0.55, 0.65, 1.0> ] [0.12 color rgb <0.30, 0.40, 1.0> ] } } finish { ambient 1 diffuse 0 } 160 ANEXO 12 landscape.pov } scale 1000 no_shadow hollow on } // -------- random seeds for the Trees ------------#declare Seed=seed(2); #declare Seed2=seed(1); // -------- Tree textures ------------#if (Test_Render) // simple textures for test renders #declare T_Wood= texture { pigment { color rgb <1, 0, 0> } } #declare T_Tree= texture { pigment { color rgb <1, 0, 0> } } #else #declare T_Wood= texture { pigment { color rgb <0.4, 0.2, 0.05> } finish { specular 0.3 diffuse 0.5 } normal { bozo 0.6 scale <0.1, 0.1, 0.5> } } #declare T_Tree= texture { pigment { agate color_map { [0.77 color rgbt 1] [0.77 color rgb <0.2, [0.85 color rgb <0.4, [0.97 color rgb <0.4, [0.99 color rgb <0.4, } scale 0.5 warp { turbulence 0.4 } } finish { diffuse 0.5 brilliance 1.5 ambient 0.07 } normal { wrinkles 0.6 scale 0.5 } } #end 0.5, 0.6, 0.6, 0.2, 0.10> 0.15> 0.15> 0.05> ] ] ] ] // -------- Tree macro ------------#macro TreeA (Size) union { cylinder { 0, Size*z, Size*0.04 } // Trunk union { // Roots cylinder { 0, -Size*0.30*z, Size*0.025 rotate (40+rand(Seed)*20)*x rotate rand(Seed2)*360*z } cylinder { 0, -Size*0.25*z, Size*0.020 rotate (40+rand(Seed)*20)*x rotate rand(Seed2)*360*z } 161 ANEXO 12 landscape.pov cylinder { 0, -Size*0.27*z, Size*0.022 rotate (40+rand(Seed)*20)*x rotate rand(Seed2)*360*z } } union { // Branches cylinder { 0, Size*0.35*z, Size*0.025 rotate (40+rand(Seed)*35)*x rotate rand(Seed2)*360*z translate Size*(0.7+0.3*rand(Seed))*z } cylinder { 0, Size*0.40*z, Size*0.026 rotate (40+rand(Seed)*35)*x rotate rand(Seed2)*360*z translate Size*(0.7+0.3*rand(Seed))*z } cylinder { 0, Size*0.27*z, Size*0.022 rotate (40+rand(Seed)*35)*x rotate rand(Seed2)*360*z translate Size*(0.7+0.3*rand(Seed))*z } } #if (Test_Render) // Foliage sphere { Size*z, Size*(0.4+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } } #else union { sphere { Size*z, Size*(0.4+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } sphere { Size*z, Size*(0.3+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } sphere { Size*z, Size*(0.2+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } sphere { Size*z, Size*(0.3+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } sphere { Size*z, Size*(0.2+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } sphere { Size*z, Size*(0.3+rand(Seed)*0.15) scale <rand(Seed)*0.5+0.5, rand(Seed)*0.5+0.5, 1> texture { T_Tree scale Size translate rand(Seed)*6 } } #end texture { T_Wood scale Size } } #end // -------- Terrain textures ------------#declare T_Sand= texture { 162 } } } } } } ANEXO 12 landscape.pov pigment { color rgb <1.1, 0.7, 0.3> } finish { specular 0.06 ambient <0.8, 0.9, 1.4>*0.1 } normal { granite 0.3 scale 0.1 } } #declare T_Grass= texture { pigment { color rgb <0.5, 1.15, 0.3> } finish { specular 0.1 diffuse 0.3 brilliance 1.6 ambient <0.8, 0.9, 1.4>*0.03 } normal { granite 0.5 accuracy 0.01 scale 0.12 } } #declare T_Rock= texture { pigment { agate color_map { [0.2 color rgb <0.55, 0.50, 0.50> ] [0.6 color rgb <0.75, 0.50, 0.60> ] [1.0 color rgb <0.70, 0.60, 0.60> ] } scale 0.2 warp { turbulence 0.5 } } finish { specular 0.2 diffuse 0.4 ambient <0.8, 0.9, 1.4>*0.06 } normal { granite 0.6 scale 0.1 } } #declare T_Terrain= texture { slope { -z*0.8 altitude z } texture_map { [0.05 T_Grass ] [0.09 T_Sand ] [0.19 T_Sand ] [0.23 T_Rock ] } translate -0.05*z } #if (use_iso) // -------- Use an isosurface for the terrain ------------#declare fnPig= function{ pigment { agate color_map { [0.0 color [0.3 color [0.7 color [1.0 color // Terrain shape function rgb rgb rgb rgb 0.0] 0.2] 0.8] 1.0] 163 ANEXO 12 landscape.pov } warp { turbulence 0.01 } scale 5 translate <1.8, -6.7, 0> } } #declare Terrain_Obj= isosurface { function { z-fnPig(x, -y, 0).gray*0.4 } max_gradient 2.8 //evaluate 1, 10, 0.99 accuracy 0.02 // for evaluating max_gradient contained_by { box { <-3, -3, -0.1>, <3, 3, 0.41> } } } #else // -------- Use a heightfield for the terrain ------------#declare Terrain_Obj= height_field { function 500,500 { pigment { agate color_map { [0.0 color rgb 0.0] [0.3 color rgb 0.2] [0.7 color rgb 0.8] [1.0 color rgb 1.0] } warp { turbulence 0.01 } scale 5 translate <1.8, -6.7, 0> translate <3, 3, 0> scale 1/6 translate -0.5*y scale <1, -1, 1> translate 0.5*y } } rotate -90*x scale <6, 6, -0.4> translate <-3, -3, 0> } #end object { Terrain_Obj texture { T_Terrain } } // -------- Placing the trees ------------#declare Spacing=0.24; #declare Cnt=0; #declare PosX=-3; #while (PosX < 3) #declare PosY=-3; #while (PosY < 3) 164 ANEXO 12 landscape.pov // trace #declare #declare #declare function Norm = <0, 0, 0>; Start = <PosX+(rand(Seed)-0.5)*Spacing, PosY+(rand(Seed)-0.5)*Spacing, 1.0>; Pos = trace ( Terrain_Obj, // object to test Start, // starting point -z, // direction Norm ); // normal #if (Norm.x != 0 | Norm.y != 0 | Norm.z != 0) // if intersection is found, normal differs from 0 #if ((vdot(Norm, z)>0.85) & (Pos.z < 0.25)) // criteria for placing trees: not too steep and not too high object { TreeA (0.05+rand(Seed)*0.02) translate Pos } #declare Cnt=Cnt+1; #end #end #declare PosY=PosY+Spacing; #end #declare PosX=PosX+Spacing; #end #debug concat("Placed ", str(Cnt,0,0), " Trees\n") 165 ANEXO 13 camera2.pov, camera2.ini ANEXO 13 camera2.pov, camera2.ini // // // // Persistence Of Vision raytracer version 3.5 sample file. File by Dieter Bayer Perturbed camera demonstration. Use povray -icamera2.pov camera2.ini to trace. global_settings { assumed_gamma 2.2 } #include "colors.inc" // camera used for perspective projection (POV-Ray standard) // looking at the center of the cage camera { perspective location <20, 30, -40> right <4/3, 0, 0> up <0, 1, 0> direction <0, 0, 1> look_at <0, 10, 0> angle 70 normal { waves 0.25 * (1 - clock) frequency 8 phase 3.14 * clock } } background { color red 0.078 green 0.361 blue 0.753 } light_source { <100, 100, -100> color Gray60 } light_source { <-100, 100, -100> color Gray60 } #declare My_Texture_1 = texture { pigment { color red 1 green 0.75 blue 0.33 } finish { diffuse 1 phong 0 phong_size 0 reflection 0 } } triangle { <50, -4, 50> <-50, -4, 50> <-50, -4, -50> texture { My_Texture_1 } } triangle { <50, -4, 50> <-50, -4, -50> <50, -4, -50> texture { My_Texture_1 } } #declare My_Texture_2 = texture { pigment { color red 1 green 0.9 blue 0.7 } finish { diffuse 0.5 phong 0.5 phong_size 3 reflection 0.5 } } /* red */ #declare My_Texture_3 = texture { pigment { color red 1 green 0 blue 0 } 166 ANEXO 13 camera2.pov, camera2.ini } finish { diffuse 0.5 phong 0.5 phong_size 3 reflection 0.5 } /* green */ #declare My_Texture_4 = texture { pigment { color red 0 green 1 blue 0 } finish { diffuse 0.5 phong 0.5 phong_size 3 reflection 0.5 } } /* blue */ #declare My_Texture_5 = texture { pigment { color red 0 green 0 blue 1 } finish { diffuse 0.5 phong 0.5 phong_size 3 reflection 0.5 } } /* yellow */ #declare My_Texture_6 = texture { pigment { color red 1 green 1 blue 0 } finish { diffuse 0.5 phong 0.5 phong_size 3 reflection 0.5 } } sphere { sphere { sphere { sphere { sphere { sphere { sphere { sphere { cylinder cylinder cylinder cylinder cylinder cylinder cylinder cylinder cylinder cylinder cylinder cylinder <+10, 0, +10>, 4 texture { My_Texture_3 } } <-10, 0, -10>, 4 texture { My_Texture_6 } } <+10, 0, -10>, 4 texture { My_Texture_5 } } <-10, 0, +10>, 4 texture { My_Texture_4 } } <-10, 20, -10>, 4 texture { My_Texture_6 } } <+10, 20, -10>, 4 texture { My_Texture_6 } } <-10, 20, +10>, 4 texture { My_Texture_6 } } <+10, 20, +10>, 4 texture { My_Texture_6 } } { <-10, 0, -10>, <+10, 0, -10>, 2 texture { My_Texture_2 } } { <+10, 0, -10>, <+10, 0, +10>, 2 texture { My_Texture_2 } } { <+10, 0, +10>, <-10, 0, +10>, 2 texture { My_Texture_2 } } { <-10, 0, +10>, <-10, 0, -10>, 2 texture { My_Texture_2 } } { <-10, 20, -10>, <+10, 20, -10>, 2 texture { My_Texture_2 } } { <+10, 20, -10>, <+10, 20, +10>, 2 texture { My_Texture_2 } } { <+10, 20, +10>, <-10, 20, +10>, 2 texture { My_Texture_2 } } { <-10, 20, +10>, <-10, 20, -10>, 2 texture { My_Texture_2 } } { <-10, 0, -10>, <-10, 20, -10>, 2 texture { My_Texture_2 } } { <-10, 0, +10>, <-10, 20, +10>, 2 texture { My_Texture_2 } } { <+10, 0, +10>, <+10, 20, +10>, 2 texture { My_Texture_2 } } { <+10, 0, -10>, <+10, 20, -10>, 2 texture { My_Texture_2 } } 167 ANEXO 13 camera2.pov, camera2.ini camera2.ini ; Persistence Of Vision raytracer version 3.5 sample file. Antialias=Off Antialias_Threshold=0.2 Antialias_Depth=3 Input_File_Name=camera2.pov Initial_Frame=1 Final_Frame=30 Initial_Clock=0 Final_Clock=1 Cyclic_Animation=on Pause_when_Done=off 168 ANEXO 14 float4.pov, float4.ini ANEXO 14 float4.pov, float4.ini // // // // // Persistence Of Vision Raytracer version 3.5 sample file. FLOAT4.POV Animate this scene with clock values +ki0.0 to +kf1.0 Demonstrate sqrt, pow, degrees & atan2 as well as Pythagorean Theorm using a 3-4-5 triangle and some boxes. global_settings { assumed_gamma 2.2 } #include "colors.inc" #declare Rad=1/6; #declare Font="cyrvetic.ttf" camera { location <0, 0, -140> direction <0, 0, 11> look_at <0, 0, 0> } light_source { <5000, 10000, -20000> color White} plane { z, Rad hollow on pigment {checker color rgb <1,.8,.8> color rgb <1,1,.8>} } #declare #declare #declare #declare #declare A=4; B=3*clock; C=sqrt(pow(A,2)+pow(B,2)); Angle_b=atan2(B,A); b_Degrees=degrees(Angle_b); union { box{0,<A,-A,1> pigment {checker Yellow , Red} } box{0,<B,B,1> pigment {checker Yellow , Blue} translate x*A } box{0,<C,C,1> pigment {checker Yellow , Green} rotate z*b_Degrees } intersection{ box{0,2} cylinder{-z,z,2} cylinder{-z,z,1.75 inverse} translate z*.1 pigment{Magenta*.7} } text{ttf Font "A=4",0.1,0 translate <1,-5,0> pigment{Red}} text{ttf Font concat("B=",str(B,1,2)),0.1,0 translate <4.25,-1.25,0> pigment{Blue}} text{ttf Font "C=sqrt(pow(A,2)",0.1,0 translate <-9,2,0> pigment{Green}} text{ttf Font "+pow(B,2))",0.1,0 translate <-7,1,0> pigment{Green}} text{ttf Font concat("C=",str(C,1,2)),0.1,0 pigment{Green} translate (C+0.3)*y rotate z*b_Degrees } text{ttf Font concat("b=atan2(B,C)=",str(Angle_b,1,2)),0.1,0 translate <-9,-1,0> pigment{Magenta*.7}} text{ttf Font concat("degrees(b)=",str(b_Degrees,1,2)),0.1,0 translate <-8.5,-2,0> pigment{Magenta*.7}} } translate x-y Float4.ini ; Persistence Of Vision raytracer version 3.5 sample file. 169 ANEXO 14 float4.pov, float4.ini Antialias=Off Antialias_Threshold=0.2 Antialias_Depth=3 Input_File_Name=float4.pov Initial_Frame=1 Final_Frame=51 Initial_Clock=0 Final_Clock=1 Cyclic_Animation=off Pause_when_Done=off 170 ANEXO 15 vect1.pov, vect1.ini ANEXO 15 vect1.pov, vect1.ini // // // // Persistence Of Vision raytracer version 3.5 sample file. File by Chris Young Demonstrates various new vector math functions. Animate this scene with clock values +k0.0 to +k1.0 global_settings { assumed_gamma 2.2 } #include "colors.inc" #declare Font="cyrvetic.ttf" // Basic clock runs from 0.0 to 1.0 but we want to move more // than that. Define a scaled version. #declare Clock360 = 360*clock; #declare ClockRot = Clock360*z; // An object that rotates one full circle of 360 degrees #declare Arm = union{ cylinder{0,3*x,.3} sphere{0,.5} sphere{3*x,.5} pigment{Red} rotate ClockRot } // A point on the object that is rotating #declare Attach_Point=vrotate(x*3,ClockRot); // A point where we will anchor the push rod #declare Fixed_Point =x*8; // This rod runs from the Attach_Point to the Fixed_Point. // It varies in length as the Arm rotates. #declare Long_Rod= union{ sphere{Attach_Point,.2} cylinder {Attach_Point,Fixed_Point,0.2 } pigment{Green} } // Use the vlength function to compute the length. #declare Long_Length=vlength(Attach_Point - Fixed_Point); // We want a fixed length short, fat rod that follows the same angle // as the long rod. Compute a unit vector that is parallel to // the long rod. #declare Normalized_Point = vnormalize(Attach_Point-Fixed_Point); #declare Short_Length=4; #declare Short_Rod= union{ sphere{0,.5} cylinder {0,Short_Length*Normalized_Point,0.5} translate Fixed_Point // move into place pigment{Blue} } union { object{Arm} union { object{Long_Rod} object{Short_Rod} translate -z/2 } translate -x*4 } 171 ANEXO 15 vect1.pov, vect1.ini text{ttf Font concat("Angle=",str(Clock360,1,1)),0.1,0 scale 2 pigment{Red} translate <3.5,3.5,0>} text{ttf Font concat("Length=",str(Long_Length,1,1)),0.1,0 scale 2 pigment{Green} translate <3.5,-5,0>} camera { location <0, 0, -120> direction <0, 0.5, 11> look_at <0, 0, 0> } light_source { <5000, 10000, -20000> color White} plane { -z, -1/3 pigment {checker color rgb <1,.8,.8> color rgb <1,1,.8>} } vect1.ini ; Persistence Of Vision raytracer version 3.5 sample file. Antialias=Off Antialias_Threshold=0.2 Antialias_Depth=3 Test_Abort_Count=100 Input_File_Name=vect1.pov Initial_Frame=1 Final_Frame=60 Initial_Clock=0 Final_Clock=1 Cyclic_Animation=on Pause_when_Done=off 172