Você está na página 1de 6

Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

Montaje de un clúster Raspberry para procesamiento paralelo basado en


programación funcional

Jorge G. HOYOS
Facultad de ingeniería de sistemas Universidad Santo Tomás
Tunja, Boyacá Colombia

Alex PUERTAS
Facultad de ingeniería de sistemas Universidad Santo Tomás
Tunja, Boyacá Colombia

ejecuciones del programa, esto en función del procesamiento


RESUMEN paralelo y el tiempo de ejecución de la aplicación.

Finalmente se observan las conclusiones, recomendaciones y


El objeto de este trabajo es realizar la instalación e
bibliografía generada a partir de este proyecto
implementación de un clúster basado en tecnologías de bajo
costo, que se estructuren como soluciones de procesamiento
distribuido y de tipo portable y que puedan estar en capacidad de 2. IMPLEMENTACIÓN FÍSICA
satisfacer necesidades en comunidades informáticas específicas.
Diseño de clúster: Como estructuración principal, se construyó
Para este particular, usando Raspberries PI 2 y Python como
un clúster con cuatro nodos de procesamiento, usando
lenguaje de programación.
Raspberries Pi 2 nombradas: pi01, pi02, pi03 y pi04, e
implementando a la primera como sistema de control y ejecución
Para desarrollar el proyecto se modificó una fuente de 400 vatios
de comandos. Para desarrollar esta tarea se tuvo en cuenta el
de salida para alimentación y se estructuró una red de datos de
siguiente esquema de ejecución: Implementación de una fuente
tipo cableado/estático, usando Raspbian Jessie, como sistema
de poder, instalación de software en los nodos del clúster y
operativo y MPI4PY como controlador del clúster, teniendo en
desarrollo de la red de comunicaciones, como se muestra a
cuenta la implementación de llaves de autenticación RSA para
continuación:
establecer comunicación entre los dispositivos físicos.
Implementación de una fuente de poder: Para dotar de
En cuanto a la programación, se llevó a cabo el diseño y
corriente a las Raspberries fue necesario implementar un tipo de
desarrollo de un programa que permite calcular el factorial de un
alimentación especial, que resultara funcional para el número de
número, usando las estructuras de las funciones lambda de
elementos conectados y el tiempo de conexión de la estructura en
Python y paralelizado a través de MPI, en función del tiempo de
general. Bajo esta premisa, se desarrolló un dispositivo basado
procesamiento y la cantidad de raspberries usadas para la
en una fuente de poder de PC conectada a dos múltiples USB
ejecución de la tarea.
estándar, que realizan este trabajo, dotando de energía al sistema.
Es así que se conectó una fuente ATX EVGA 400W Power
Palabras Claves: clúster Raspberry, programación funcional,
Supply, a través de sus plugs de +5V con 17A totales, a dos
tecnología MPI y Procesamiento Paralelo.
multiplicadores de puertos USB 2.0 de 7 puertos con encendido
independiente, como los se muestra en la figura 1:
1. INTRODUCCIÓN
Figura 1: Conexión Fuente - Multiplicador USB 2.0
En primera instancia, en este documento, se encuentra el diseño
de la estructura general del clúster, en función tanto, del sistema
operativo y lenguaje de programación usado, como de los
dispositivos de hardware implementados para el montaje físico
en una red de comunicaciones que también se encuentra
documentada. En este apartado puede apreciarse el desarrollo del
clúster, en función de las conexiones y procesos de instalación de
sus sistemas de control y comunicación, en este caso MPI, sin
dejar de lado las diferentes aplicaciones instaladas para el acceso
y modificación del sistema.

Como segundo punto del documento, está consignado lo


referente a la programación de aplicaciones, en este caso, usando
el paradigma funcional y Python como lenguaje de desarrollo. En
este punto se pueden apreciar, tanto las ejecuciones del algoritmo
desarrollado, como los análisis comparativos de las diferentes
Fuente: Los autores

142
Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

Esta conexión se realizó a través del puerto USB de entrada del Figura 3: Detalle de la conexión al servidor VNC
multiplicador. Es de notar que al usar estos dispositivos como
fuente de poder, debieron retirarse sus reguladores de amperaje,
dado que estos limitan la salida de cada uno de sus puertos a
0.5A, lo cual resulta siendo insuficiente para los requerimientos
mínimos de funcionamiento del dispositivo incluyendo sus
periféricos vía USB(1.5A)[1]. Para la implementación final se
armaron las carcasas de los multiplicadores de tal suerte que
puedan usarse de forma independiente, dejando uno de ellos
como encendido general de la fuente.

Figura 2: Fuente - Multiplicador USB 2.0 terminada

Fuente: Los autores

Instalación de MPICH: Para continuar la instalación, se


incorporó al sistema la librería de MPI (Messaging Passing
interface), denominada MPICH que se usó para la sincronización
del clúster, teniendo en cuenta el procesamiento en paralelo, dado
que este modelo es usado en casos donde los nodos poseen
memoria independiente, como en este y además permite
implementar procesos dentro de una sola máquina o en un arreglo
de estas [3].

Para esta instalación, se creó una carpeta denominada MPICH y


dentro de ella se implementó el comando wget
Fuente: Los autores http://www.mpich.org/static/downloads/3.1/mpich-3.1.tar.gz
teniendo en cuenta, como lo menciona la línea de texto, la versión
Instalación de software en los nodos del clúster: Para 3.1 para este ejercicio [4].
implementar el sistema operativo en los dispositivos, se usó
Raspbian en su versión 2016-02-09-raspbian-jessie el cual se Figura 4: Implementación de mpich
instaló en una tarjeta micro SD clase 10 usando el programa
WIN32 Disk Imager. Acto seguido se conectó una de las
raspberries usando teclado, mouse, conexión a internet (de forma
cableada) cable HDMI para el video y un conector para energía
[2].

Se procedió a expandir la memoria de la Raspberry. Esto tiene


por objeto usar todo el espacio de la tarjeta, lo cual es de gran
utilidad en caso de actualizaciones e instalación de contenidos.
Luego se seleccionaron, tanto el idioma como la zona temporal y
el tipo de teclado para la interfaz del dispositivo, y por último, se
cambió el nombre de la Raspberry a pi01 para efectos de
identificación en el clúster

Después de lo anterior, se procedió a actualizar el sistema


operativo, mediante el comando apt-get update desde el modo
de súper usuario. Después, para administración remota, se instaló Fuente: Los autores
un servidor VNC en el dispositivo, en este caso tightvncserver,
cuyo servició se inició, usando el comando vncserver: 1 - Después de descomprimir el archivo, se crearon dos carpetas, una
geometry 1280x768 teniendo en cuenta que el parámetro: 1 se en la ruta de instalación del programa, en este caso /rpimpi/mpi-
refiere al número de escritorio remoto y geometry a la resolución install en el /home/pi de la pi01 y la otra mpi-build para los
del dispositivo que conectará con la interfaz. procesos de construcción e instalación de MPICH. Finalmente,
se usaron los comandos make y make install para terminar con
Para el cliente VNC se usó la aplicación Ultra VNC Viewer, este proceso.
desde el equipo remoto, tal como puede apreciarse en la figura 3:
Instalación de Python: debido a la selección de este lenguaje de
programación para realizar las pruebas respectivas, en torno al
paradigma funcional, se instalaron dos aplicaciones básicas en
este orden: Python-dev para poder realizar la compilación del
código fuente y MPI4PY que está compuesta por estructuras
MPI uno y dos que paralelizan los procesos de los programas

143
Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

desarrollados y es un módulo de Python, directamente asociado IP de los equipos de procesamiento del clúster, y que fue usado
a MPICH [5]. como parámetro para la ejecución del programa en paralelo.

Es de notar que para la instalación de MPI4PY se obtuvo el Figura 7: Detalle del archivo nodos en pi01
archivo mediante wget
https://bitbucket.org/mpi4py/mpi4py/downloads/mpi4py-
1.3.1.tar.gz Este archivo se descomprimió, y a través del
comando Python setup.py build se construyó la aplicación, para
ser utilizada dentro del clúster.

Figura 5: Detalle de la instalación de MPI4PY

Fuente: Los autores

Implementación de llaves de autenticación: Para lograr la


conexión entre las diferentes raspberrries, se procedió a la
creación de llaves de autenticación, en cada uno de los nodos,
con esquema público/privado usando RSA, debido a que sin esto,
no es posible tener autorización desde MPI para el uso de
recursos distribuidos[6].

Figura 8: Creación de llave de autenticación

Fuente: Los autores

En última instancia, se procedió a realizar la revisión de la


instalación de todos los programas necesarios para el
funcionamiento del clúster, además de exportar en el PATH de la
Raspberry la ruta de MPI4PY.

Figura 6: Detalle del funcionamiento del paralelizador

Fuente: Los autores

Después de creadas todas las llaves, se compartieron entre las


Raspberries, teniendo en cuenta que se copió la llave de pi01 en
cada una de ellas, para luego, desde pi01 traer las llaves de pi02,
pi03 y pi04, de tal suerte que todos los nodos conozcan a pi01 y
pi01 conozca a todos los nodos del clúster.

Estructura Final: Al final, desde el punto de vista físico se logró


Fuente: Los autores el siguiente resultado, teniendo en cuenta todas las
consideraciones anteriores.
Desarrollo de la red de comunicaciones: Para esta
implementación se utilizó una red cableada entre los dispositivos Figura 9: Implementación Final
y un concentrador, para este caso un switch TP-LINK TL-
SG1016 de 16 puertos Gigabit Ethernet no administrable, con
cables UTP categoría 6 para conexión física con las Raspberries.

Montaje de dispositivos: Terminado el proceso de instalación


sobre un dispositivo, se procedió a clonar la imagen trabajada en
pi01 en otras tres memorias de tipo MicroSD Clase 10, a través
de la herramienta Win32DiskImager. Estas ISO se instalaron
sobre las demás Raspberries, que fueron llamadas pi02, pi03 y
pi04 respectivamente.

En cuanto al direccionamiento, se implementaron direcciones


estáticas en cada una de los dispositivos, usando el dominio
Fuente: Los autores
192.168.0.0/24 como base y haciendo las pruebas de
conectividad respectivas. Realizado lo anterior, se escribió un
archivo llamado nodos en la pi01, el cual contiene las direcciones

144
Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

3. IMPLEMENTACIÓN DEL PROGRAMA En segundo lugar, la función lambda interna, tomaba dos
FUNCIONAL parámetros de funcionamiento, notados por (x,y) en el código.
Con ello la función usaba los valores que estaban en las dos
Diseño de la aplicación: Para probar los parámetros de primeras posiciones del rango, en este caso uno (1) y dos (2) para
programación funcional se usó Python como lenguaje de ejecutar alguna operación con ellos. Ahora bien, reduce, le
aplicación, dado que cuenta con funciones lambda permite a Python aplicar una función dada a cada par de
implementadas dentro del mismo. En cuanto al algoritmo elementos de una lista, de tal suerte que se puedan simplificar en
matemático, se seleccionó el del factorial de un número. Así que, un solo dato [9], así pues el producto de estos números, notado
de forma general se desarrolló un programa, denominado fac.py por x*y en el programa, se transformaba en la siguiente x de la
que realizara este cálculo, como se muestra a continuación: operación del factorial, la cual se multiplicaba por el valor tres
(3) que se encontraba en la tercera posición de la lista. Este
Figura 10: programa para cálculo del factorial del número 33 proceso se repetía, de forma recursiva hasta llegar al final de la
usando Python lista, obteniendo así el factorial de un número dado.

Por otra parte, las variables tiempoi y tiempof se usaron para


medir el tiempo de ejecución del programa, para ello se tomaron
dos timesptamps [10] (en segundos), uno antes de la ejecución
del factorial y otro después del mismo, luego se calculó la
diferencia entre ambos y se guardó en una tercera variable
Fuente: Los autores denominada tiempoe, cuyo contenido era una aproximación al
tiempo de ejecución de la función desarrollada. Esta variable se
Como eje central del programa está la función fac implementada imprimió por pantalla, de tal suerte que se tuviera un registro del
a partir de una función Lambda recursiva como puede verse en la proceso.
figura 10. Esta contiene las validaciones respectivas del factorial
de un número, teniendo en cuenta tanto, la inclusión de un Por otra parte, se incluyó la línea de código
número negativo en cuyo caso, por definición su factorial no está sys.setrecursionlimit(2000) que permitía ampliar la cola de
definido, cómo el valor del factorial del número cero (0) que procesos recursivos, mediante la modificación del valor del
siempre es el valor constante uno (1)[7] Ahora bien, si el valor número de funciones anidadas que soporta la aplicación [11], que
ingresado era un número positivo mayor que cero, se calculaba por defecto es de 1000, lo cual previene volcados de pila en los
su factorial con base en la reducción del producto del rango programas ejecutados. Ahora bien, dado lo anterior no era posible
comprendido entre uno (1) y el número ingresado, usando una ejecutar el factorial de 2.000.000, así que se optó por subir el
función lambda con dos parámetros (x,y) la cual realiza esta valor a 2000 funciones mediante la línea de código citada.
multiplicación, como puede apreciarse a continuación:
Continuando con la explicación del código, la ejecución de la
Figura 11: Funcionamiento del cálculo de un factorial con la función que calcula el factorial de un número, se implementó
función implementada mediante la línea fac(2000000) en el programa, siendo 2.000.000
el valor de entrada n en la función lambda. Esta función se
embebió dentro de un print, con el fin de poder mostrarla por
pantalla al momento de la ejecución del código.

También es de notar que se usaron tres imports en la construcción


del programa: se trajeron los componentes de sys para el manejo
de funciones anidadas, análogamente se hizo lo mismo desde
functools y time, para poder utilizar las herramientas reduce y
time respectivamente.

Por último se realizaron pruebas del funcionamiento de la


Fuente: Los autores aplicación usando valores conocidos de factoriales de números,
como puede observarse a continuación:
En la figura 11, se muestra el cálculo del factorial del número
cinco (5) como ejemplo de explicación en el programa: Como Figura 13: Ejecución del programa con el número 33 como
primera medida la estructura range(1, n+1) permitía crear una parámetro
lista de números para el cálculo del factorial [8], el número uno
(1) indicaba la cota inferior, en tanto que n+1 representaba la
superior. Es de notar que n se incrementó en uno, dado que en
Python el límite superior de un rango es abierto, por ende no
incluía el número propiamente dicho:
Fuente: Los autores
Figura 12: Diferenciación de rangos en Python
4. PRUEBAS DE FUNCIONALIDAD MEDIANTE
EJECUCIÓN PARALELA EN EL CLÚSTER

Para finalizar este estudio se diseñó una prueba en donde se


ejecutó fac.py para número dos millones de forma paralela el
arreglo de equipos.
Fuente: Los autores

145
Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

En esta prueba se tuvieron en cuenta dos aspectos fundamentales: Figura 16: Ejecución de proceso en el clúster para cinco
En primer lugar se ejecutó el programa utilizando MPI en un solo procesos
nodo del clúster, implementando de 1 a 8 procesos en la máquina
seleccionada en 10 ejecuciones diferentes para cada uno. Al final
de cada intento se registró el tiempo de duración y se realizó el
promedio de las 10 iteraciones, con el fin de obtener la media de
los datos obtenidos, los cuales fueron tomados como información
de control en este ejercicio. En segundo lugar se desarrolló esta
misma medición usando ahora los cuatro nodos componentes del
clúster, y se realizaron las comparaciones contra los datos de base
teniendo como variables de medición: El tiempo de ejecución del
programa, la cantidad de procesos paralelos y el número de Fuente: los autores
dispositivos físicos utilizados para esta tarea.
La figura16, muestra el comando de ejecución del programa para
Ejecución para un solo nodo: la ejecución del programa se cinco procesos y sus correspondientes imágenes en cada uno de
desarrolló mediante el comando mpiexec en la terminal de Linux los nodos del clúster. Al finalizar la ejecución, los resultados del
sobre la Raspberry. Es de notar que debido al diseño del clúster, procesamiento de cada una de las máquinas fueron condensados
todas estas pruebas aplicaron desde la pi01 como puede en una sola respuesta en pi01.
observarse a continuación:
Figura 17: Respuesta de la aplicación para 7 procesos en
Figura 14: Detalle de la ejecución del programa paralelizado en paralelo
pi01

Fuente: los autores

Al establecer la comparación entre el procesamiento paralelo


usando una sola máquina (pi01) y el clúster implementado con
Fuente: Los autores cuatro nodos, fue posible determinar las diferencias de tiempo en
el procesamiento de las peticiones solicitadas por consola
La figura 14, muestra el desarrollo en paralelo del programa para
3, 5 y 8 procesos en un solo nodo del clúster. Es importante tener Figura 18: Comparación de tiempos de ejecución entre
en cuenta que fac.py se ejecutó paralelamente cómo tantos
paralelismo en una máquina y en un clúster
procesos fueron desplegados, es decir con n = 3 el código se
implementó 3 veces en pi01. También cabe anotar que la
ejecución del paralelizador se logró mediante el comando
mpiexec y que se registraron evidencias de los procesos dentro
de la máquina, como puede observarse a continuación con un n
= 8 y usando el comando top –p numero_de_proceso en una
terminal Linux.

Figura 15: Ejecución de fac.py para n = 8 en pi01

Fuente: Los Autores

Para observar la cantidad de procesos implementados en el


clúster, se procedió a contar las apariciones de fac.py en cada una
Fuente: Los autores de los registros de memoria en las Raspberries del sistema, luego
se graficaron los procesos totales de las ejecuciones, es decir
Ahora bien, para realizar la implementación del clúster, se desde uno (1) hasta ocho (8) versus la cantidad de procesos
realizaron las mismas pruebas utilizando la estructura de mpiexec creados en cada máquina en cada ejecución:
desde pi01, como control de sistema, teniendo en cuenta la
utilización del archivo nodos como parte de la sentencia del
programa, usando la herramienta f del comando de ejecución y
obteniendo los siguientes resultados:

146
Memorias de la Séptima Conferencia Iberoamericana de Complejidad, Informática y Cibernética (CICIC 2017)

Figura 19: Cantidad de procesos en los nodos del clúster Sin embargo también cabe anotar que los datos obtenidos están
sujetos también a las colas de procesos de cada uno de los nodos
y a las condiciones de temperatura y manejo general de los
mismos.

Python ofreció una gran versatilidad al momento de abordar el


paradigma funcional, como forma de implementación de
programas en el clúster desarrollado, dado a que contiene una
sintaxis de fácil comprensión y utilización para este tipo de
procedimientos.

6. REFERENCIAS

[1] Monk, Simon. Raspberry Pi cookbook: Software and


hardware problems and solutions. " O'Reilly Media, Inc.",
2016. Pág. 5.
Fuente: Los autores
[2] Monk, Simon. Raspberry Pi cookbook: Software and
hardware problems and solutions. " O'Reilly Media, Inc.",
Como puede observarse en la figura 19, el nodo pi01 fue quien
2016. Pág. 15.
más ejecutó el proceso durante todo el ejercicio, con un total de
[3] Zaccone, Giancarlo. Python Parallel Programming
12 implementaciones y presencia en todas las pruebas
Cookbook. Packt Publishing Ltd, 2015. Pág. 15
programadas.
[4] Zaccone, Giancarlo. Python Parallel Programming
Cookbook. Packt Publishing Ltd, 2015. Pág. 98
De una forma más general, el porcentaje de uso de recursos en el
[5] Zaccone, Giancarlo. Python Parallel Programming
clúster se puede observar de la siguiente manera:
Cookbook. Packt Publishing Ltd, 2015. Pág. 99
[6] Vega, Isidro Robledo. "INFORME FINAL DEL
Figura 20: Porcentajes de utilización de los nodos del clúster
PROTOTIPO:“Cluster Beowulf de 16 Nodos”. 2009. Pág. 7
[7] Da Rosa, Sylvia, Beatriz Frioni, y Nélida Giraldez.
"Funciones Recursivas." Pág. 24
[8] Driscoll Michael. Python 101. Learnpub. 2016. Pág. 36
[9] Lutz, Mark. Learning python. " O'Reilly Media, Inc.", 2013.
Pág. 576.
[10] Driscoll Michael. Python 101. Learnpub. 2016. Pág 138.
[11] Goodrich, Michael T., Roberto Tamassia, y Michael H.
Goldwasser. Data structures and algorithms in Python. John
Wiley & Sons Ltd, 2013. Pág. 168.

Fuente: Los autores

5. CONCLUSIONES

Como una conclusión general, es importante anotar que es


posible desarrollar una aplicación en paralelo a bajo costo y poco
espacio físico de utilización, usando herramientas de Hardware y
Software libre que supla necesidades de procesamiento para
tareas de esta índole y que, usando el paradigma funcional,
permita realizar operaciones a partir de funciones lambda
ahorrando codificaciones mayores, debido a las asignaciones de
memoria y tipos de variables utilizadas, sobre todo teniendo en
cuenta el cálculo para números de gran tamaño, como fue en este
caso, además, con la utilización de tecnología MPI para la
ejecución paralela de aplicaciones fue posible lograr
sincronización de los procesos ejecutados en paralelo, de una
forma cómoda para el usuario de la aplicación y de forma
independiente en cada una de los nodos de procesamiento.

Por otra parte, la utilización de clústeres de procesamiento


funciona como una forma de optimización de procesos, ya que es
posible ejecutar múltiples ejecuciones de un mismo programa en
las diferentes máquinas que lo componen.

147

Você também pode gostar