He empezado a aprender como hacer compilación paralela para obtener más rendimiento en el clúster. Para ello me he metido con OpenMPI que es un proyecto abierto derivado de la estructura LAM/MPI mantenido por la comunidad.
El primer paso es obtener el software de esta dirección y compilarlo:
$ tar jxvf openmpi-1.4.1.tar.bz2 $ ./configure --prefix=/usr/local/openmpi # make all install
Una vez compilado, debemos actualizar el enlazador dinámico para que nuestro software enlace correctamente con las librerías dinámicas de OpenMPI
# ldconfig /usr/local/openmpi/lib
Con esto, le decimos al programa ld que busque en /usr/local/openmpi/lib las librerias que haces falta en tiempo de ejecución de nuestro programa.
A continuación, es obligatorio que todos los nodos del clúster tengan acceso a los ejecutables tanto de nuestro programa como de OpenMPI, por lo que vamos ha crear un par de comparticiones por NFS.
/usr/local/openmpi 192.168.0.0/24(ro,root_squash) /home/openmpi 192.168.0.0/24(rw,root_squash)
Donde /home/openmpi es nuestro usuario de cluster, en su directorio $HOME estará el programa a ejecutar. Y la otra compartición contiene los ejecutables del compilador.
Vamos a lanzar el programa clásico HelloWorld en paralelo, para ello utilizamos el siguiente código.
/* helloworld.c */ /* http://www.semicomplete.com/presentations/mpi/#slide_2 */ #include <stdio.h> /* Esto es para añadir las funciones de OpenMPI */ #include "mpi.h" int main(int argc, char **argv) { int rank; char host[150]; int namelen; /* Inicializar MPI. Maneja la línea de comando especifica de mpich */ MPI_Init(&argc, &argv); /* Devuelve el rango. Mi número de rango (de la instancia del programa) queda almacenado en la variable rank */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Vemos en qué maquina me ejecutando y lo guardamos en host */ MPI_Get_processor_name(host,&namelen); printf("Hello world (Rank: %d / Host: %s)\n", rank, host); fflush(stdout); /* Fin: Cerramos las conexiones con los demás nodos y liberamos la memora que el programa ha reservado,... */ MPI_Finalize(); return 0;
Lo compilamos
$ PATH=$PATH:/usr/local/openmpi/bin $ mpicc helloworld.c -o helloworld
El PATH podemos añadirlo a nuestro ~/.bashrc para que esté siempre disponible. Ejecutamos.
$ mpirun -np 5 --hostfile=hosts helloworld
Donde
- -np Es el número de procesos que vamos a lanzar.
- –hostfile Es el fichero que almacena los nombres de los hosts, cada nodo del cluster.
La salida debe ser algo como esto
Hello world (Rank: 0 / Host: master) Hello world (Rank: 2 / Host: master) Hello world (Rank: 4 / Host: master) Hello world (Rank: 1 / Host: cluster01) Hello world (Rank: 3 / Host: cluster01)
Vemos que ha lanzado tres procesos en master y dos en cluster01.
De momento esto es lo poco que sé, pero sigo avanzando, el asunto de tener que resolver matrices de gran tamaño voy a necesitar escribir código para lanzar paralelizado.