2016-09-01 2 views
1

Dans le problème spécifique que je traite, les processus disposés dans une topologie 3D doivent échanger des parties d'un tableau 3D A(:,:,:) entre eux. En particulier, chacun doit envoyer un nombre donné de tranches de A aux processus dans les six sens orientés (par exemple A(nx-1:nx,:,:) au processus dans la 1ère dimension positive, A(1:3,:,:) dans la négative, A(:,ny-3:ny,:) dans la dimension y positive, et bientôt). Pour ce faire, je vais définir un ensemble de types de sous-réseau (au moyen de MPI_TYPE_CREATE_SUBARRAY) à utiliser dans les communications (peut-être MPI_NEIGHBOR_ALLTOALL, ou son extension V ou W). La question est de ce que le meilleur choix, en termes de performance, entre:MPI - communique 1 élément d'un gros type ou plus d'éléments d'un petit type?

  • définissent 3 sous-zones (une pour chaque dimension), chacun étant en fait un tableau 2D, puis faire envoyer les communications le long de chaque une dimension différent nombre de ces types dans les deux directions, ou
  • définir 6 sous-réseau (un pour chaque direction orientée), chacun étant toujours un tableau 3D, puis faire les communications envoyer le long de chaque dimension un élément des deux types dans le deux directions?

Enfin, pour être plus général, comme dans le titre, est-il préférable de définir plus MPI dérivée des types de données « de base » et l'utilisation counts supérieur à 1 dans les communications, ou de définir des types « grandes » et et utiliser counts = 1 dans les communications?

Répondre

2

Les types de données dérivés de MPI sont définis pour fournir à la bibliothèque un moyen d'empaqueter et de déballer les données que vous envoyez.

Pour les types de base (MPI_INT, MPI_DOUBLE, etc.), il n'y a pas de problème car les données en mémoire sont déjà contiguës: il n'y a pas de trous dans la mémoire.

Les types plus complexes tels que les tableaux multidimensionnels ou les structures, l'envoi des données comme peuvent être inefficaces en raison du fait que vous envoyez probablement des données inutiles. Pour cette raison, les données sont empaquetées dans un tableau contigu d'octets, envoyées à la destination, puis décompressées à nouveau pour restaurer leur forme d'origine. Cela étant dit, vous devez créer un type de données dérivé pour chaque forme différente dans la mémoire. Par exemple, A(1:3,:,:) et A(nx-2:nx,:,:) représentent le même type de données. Mais A(nx-2:nx,:,:) et A(:,nx-2:nx,:) ne le font pas. Si vous spécifiez correctement l'accès à la foulée (l'intervalle entre les types de données consécutifs), vous pouvez même spécifier un type de données dérivé 2D, puis modifier l'argument count pour obtenir une meilleure flexibilité de votre programme. Enfin, pour répondre à votre dernière question, cela vaut probablement la peine d'effectuer une analyse comparative, même si je pense que la différence ne sera pas très nette puisqu'elle aboutira à un seul message MPI dans les deux cas.