next up previous contents
Next: 4.2.3.2 PVM Up: 4.2.3 Implementación Previous: 4.2.3 Implementación   Índice General

4.2.3.1 MPI

El programa de multiplicación de matrices paralelo utilizando MPI se muestra en el apéndice (A.1.3).

El primer paso para utilizar MPI en un programa es inicializar el mecanismo de paso de mensajes. Esto se hace por medio de la llamada MPI_Init (línea 31). A continuación el proceso determina el tamaño de su comunicador (cuántos procesos lo componen) con una llamada a MPI_Comm_size (línea 36) . El comunicador, o contexto de comunicaciones, es el grupo de trabajo básico de MPI; en general, un comunicador delimita el alcance de llamadas a funciones grupales, como broadcasts y scatter/gather. Esto facilita la organización y distribución de trabajo. En este caso, se utiliza el comunicador MPI_COMM_WORLD, que es el comunicador al que pertenecen inicialmente todos los procesos. Obviamente cada proceso puede posteriormente cambiar a otro comunicador, pero en este caso es suficiente el uso de MPI_COMM_WORLD.

Se determina también el rango del proceso dentro del comunicador (es decir, qué posición ocupa de entre los procesos que componen el comunicador) y el nombre del procesador en que se está ejecutando, llamando a MPI_Comm_rank y
MPI_Get_processor_name (líneas 36 y 37). El rango es de particular utilidad para determinar cuáles renglones debe resolver cada proceso, según se describió en la sección (3.2.2).

A continuación se realiza la bifurcación de trabajo en el proceso; es decir, se designa un proceso para que asuma el papel de maestro, mientras los demás se configuran como esclavos. Basándose en el parámetro localid, el rango dentro del comunicador, a partir de la línea 74 y hasta la 169 se encuentra el trabajo que realiza el proceso maestro; de la línea 170 a la 262 se encuentran las instrucciones para los procesos esclavo.

En este caso el criterio de decisión es designar como maestro al proceso que tiene localid de 0. En MPI esta decisión es un tanto arbitraria, en realidad se puede escoger cualquier proceso como maestro, sin embargo el utilizar al proceso 0 es por convención. Esto obedece al hecho de que en MPI no se tiene el concepto inherente de ``proceso padre''. Como se verá en la sección 3.2.3, PVM sí cuenta con dicho concepto y existe un proceso que está identificado como padre de los demás.

El proceso padre genera las matrices aleatorias y las transmite a todos los procesos del comunicador MPI_COMM_WORLD. Esto se hace por medio de dos llamadas consecutivas a MPI_Broadcast. Aquí se indica la dirección de los datos a transmitir, la cantidad de información que se desea enviar, el rango del proceso raíz, y el comunicador. El parámetro de proceso raíz indica cuál proceso va a iniciar el broadcast.

Nótese que en general, las llamadas a primitivas de comunicación en MPI requieren especificar la dirección de los datos a enviar o recibir, así como el tamaño o cantidad de información a comunicar.

Una vez enviadas las matrices, el proceso padre no realiza ninguna tarea de cálculo, únicamente espera a recibir los renglones completos por parte de los nodos. Esto se hace en un ciclo que contabiliza el número de renglones recibidos (línea 129), y en cada iteración realiza una llamada a MPI_Recv (línea 135). Esta llamada bloquea en espera de recepción de un mensaje de cualquier proceso del comunicador (parámetros MPI_ANY_SOURCE y MPI_COMM_WORLD).

Al terminar de recibir los renglones el proceso padre muestra el tiempo empleado en el cálculo y termina su ejecución.

A partir de la línea 170, los procesos esclavo (con localid diferente de 0) asignan memoria para las matrices a operar y reciben sus valores por medio de broadcast. Obsérvese que en MPI la llamada a MPI_Broadcast es igual para recibir información. Los procesos cuyo localid sea diferente al especificado en la llamada, recibirán la información del proceso que inició el broadcast.

En las líneas 200-209, los procesos esclavo determinan la sección de la matriz que deben resolver.

Una vez teniendo la información necesaria, los nodos comienzan a resolver su porción de la matriz, guardando el resultado parcial de cada renglón en un arreglo y enviándolo al proceso maestro cuando se ha completado un renglón. Esto se hace por medio de una llamada a MPI_Send (línea 254). Esta función toma como parámetros la dirección y tamaño de la información a enviar, el tipo de datos (en este caso MPI_INT), el proceso destino (en este caso 0, el proceso padre), una bandera identificadora de mensaje y el comunicador al que se debe enviar el mensaje.

Los nodos continúan con este proceso hasta terminar el cálculo de sus renglones asignados, en este momento terminan su ejecución.


next up previous contents
Next: 4.2.3.2 PVM Up: 4.2.3 Implementación Previous: 4.2.3 Implementación   Índice General
2002-05-15