A.LEGRAND
Y.ROBERT
En effet, la mode actuelle en matière de calcul distribué et parallèle est à l'interconnection, via des liens à très haut débit, de grands centres de calculs disséminés à l'échelle d'un pays, d'un continent voire du monde. C'est ce que l'on appelle le meta-computing. Personne ne sait si on pourra un jour exploiter correctement de telle plateformes mais, dixit Al. Geist (responsable du projet PVM) il y a quelques jours1: "Il y a de toutes façons tellement d'argent investi dans ce domaine que cela aboutira forcément à quelque chose".
Mais revenons à MPI. Un des gros problème auquel on se heurte dès que l'on essaie d'utiliser un programme MPIsur une plateforme de meta-computing est que les bibliothèques MPId'un centre de calcul à l'autre ne sont pas forcément identiques et rien dans le standard n'oblige une bibliothèque à perdre en performance pour être compatible avec une bibliothèque concurrente. À cela s'ajoutent la difficulté de déploiement d'un tel programme, la nécessité de prendre en compte ( autant au niveau algorithmique qu'au niveau système) l'hétérogénéité des processeurs et des réseaux, le coût énorme des synchronisations et donc des opérations bloquantes, la non-tolérance aux pannes,...Même s'il serait plaisant de pouvoir programmer et utiliser ces plateformes comme une simple station de travail, nous en somme très loin actuellement et leur complexité semble rendre cette entreprise un peu utopique.
Ce portrait de MPIet du calcul parallèle actuel peut sembler un peu pessimiste mais tous ces projets ont aussi donné naissance à de très bonnes choses. Même si MPIn'est plus adapté aux plateformes de calcul telle qu'elles sont envisagées actuellement, l'aventure MPIest quand même un succès étant donné qu'elle a permis à bon nombre de personnes non informaticiennes de développer des programmes efficaces pour les plateformes de calcul parallèle classiques et de collaborer grâce à des codes portables. L'émulation créée par ces projets ambitieux de global-computing permet à bon nombre de scientifiques non informaticiens de résoudre des problèmes qu'ils n'auraient jamais pu espérer résoudre il y a de cela quelques années. Enfin, même si tous ces projets semblent un peu fous et extrêmement ambitieux, il est indéniable que la communauté scientifique a un besoin toujours croissant de puissance de calcul et de communication et que nous ne sommes actuellement pas en mesure de répondre à leurs besoins.
Un nouveau standard MPI-2 a été mis en place il y a quelques années et résout certains des problèmes précédemment évoqués. Il existe cependant encore très peu de bibliothèques mettant en uvre l'intégralité du standard MPI-2.
int MPI_Init(int *argc, char ***argv)Cette fonction initialise les connections MPIen fonction des arguments passés à votre programme. C'est pourquoi avant de lire les arguments de votre programme, il convient de faire un appel à cette fonction.
Un programme MPIse termine généralement par l'appel de la fonction MPI_Finalize. Tous les processus doivent appeler ce programme avant leur terminaison. Cette opération est bloquante ne termine que lorsque toutes les opérations de communications en cours ou en attente sont terminées.
Il peut être utile de savoir combien de processus participent au calcul et quel numéro on a. Les fonctions MPI_Comm_size et MPI_Comm_rank dont le prototype est le suivant. Un MPI_Comm est un groupe de processus MPI. Pour l'instant, nous n'utiliserons que le groupe prédéfini MPI_COMM_WORLD qui regroupe l'intégralité des processus MPIparticipant au calcul.
int MPI_Comm_size ( MPI_Comm comm, int *size ) int MPI_Comm_rank ( MPI_Comm comm, int *rank )
int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm ) int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status )
Quelques explications :
Enfin une autre fonction qui s'avère souvent utile : la barrière de synchronisation.
int MPI_Barrier ( MPI_Comm comm )
Nous allons essayer de simuler la fonction MPI_Bcast dont le prototype est le suivant.
int MPI_Bcast ( void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm )Cette fonction est bloquante. Lorsqu'un programme alterne des phases de calcul et des phases de communications, il y a donc intérêt à ce que l'équilibrage de charge soit parfait...
int MPI_Isend( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request ) int MPI_Irecv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request )request est un "numéro" de communication. Cela permet de savoir si une communication est terminée ou pas, notamment grâce à la fonction MPI_Test ou à la fonction MPI_Wait.
int MPI_Test ( MPI_Request *request, int *flag, MPI_Status *status) int MPI_Wait ( MPI_Request *request, MPI_Status *status)flag reçoit la valeur vrai si la communication est effectivement terminée.
L'objectif de ce TD était de mettre en valeur un certain nombre de limitations de MPI. Il ne faut quand même pas oublier que ces bibliothèques sont quand même très efficaces sur des plateformes homogènes, qu'elles offrent une quantité d'opérations globales impressionnantes ainsi qu'un haut niveau d'abstraction, ce qui permet de développer très rapidement un programme parallèle.
Les fichiers C solutions au problème sont disponibles
dans http://www-id.imag.fr/Laboratoire/Membres/Legrand_Arnaud/algopar/MPI/src/(broadcast1.c, broadcast2.c, broadcast3.c,
broadcast4.c, broadcast5.c).