Принудете MPI_Send да използва протокол за нетърпение или рандевуз

Правя малка MPI (openmpi) програма на C за семинар в колежа. Нашата цел е да наблюдаваме разликата във времето между двата основни протокола на MPI, eager и rendezvous, по отношение на размера на съобщението.

Не сме работили с MPI преди и си помислихме, че може да има начин за „избор“ между двата протокола. Търсейки в google информация как да го направя, намерих (някъде не помня), че има ограничение на нетърпението. Четох, че се задава от изпълнението на MPI и също така, че можете да го промените по някакъв начин.

Някакви съвети как да избирам между протоколите? Има ли някаква връзка между протоколите и MPI_Send/MPI_Isend?

Мислех, че промяната на размера на буфера на приемника ще се счупи от нетърпение и ще започне да използва рандеву. Но това е само предчувствие.

Ето моят код за сега:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "mpi.h"


#define KBdata 32000 //openmpi default buffer size
#define ndata KBdata/4 //number of ints that fits in buffer

int main(int argc, char *argv[]) {

    int myid, numprocs;
    int tag,source,destination,count;
    int buffer[ndata];
    MPI_Status status;
    MPI_Request request;

    int iter = 20;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);

    if (myid == 0 && numprocs == 2) { //to 
        int recvID = 1;
        double acum = 0;
        int i;
        double startT;
        for (i=0;i<iter;++i)
        {
            double startTime = MPI_Wtime();

            MPI_Send(&buffer,ndata,MPI_INT,recvID,0,MPI_COMM_WORLD);

            double endTime = MPI_Wtime();
            double elapsed = endTime - startTime;
            acum += elapsed;
            printf("%d, %f, elapsed: %f\n",i,acum,elapsed);fflush(stdout);
            usleep(500000);
        }
        printf("total: %f\nmean: %f\n", acum, acum/iter);   
    }
    else if (numprocs == 2) {
        int i;
        for(i=0; i<iter; ++i)
        {
            printf("Waiting for receive\n");fflush(stdout);
            MPI_Recv(&buffer,ndata,MPI_INT,0,0,MPI_COMM_WORLD,&status);
            printf("Received %d\n",i);fflush(stdout); 
        }
    }
    else {
        printf("Need only 2 threads\n");
    }

    MPI_Finalize();


    return 0;
}

Благодаря ви за съвета.


person Borja Arias    schedule 16.12.2014    source източник
comment
Размерите на буферите и протоколите са специфични за всеки тип мрежова връзка, поддържана от Open MPI, и могат да се избират чрез предаване на съответните MCA параметри. Използвайте ompi_info --param btl <type>, където <type> е типът на свързване, напр. openib, tcp и т.н., за да получите списък с всички параметри за дадения BTL.   -  person Hristo Iliev    schedule 17.12.2014
comment
В MPICH бихте задали това с променлива на средата. Потърсете 'EAGER' в изхода на mpivars. Cray MPI, макар и базиран на MPICH, използва малко по-различен механизъм за променливи на средата.   -  person Rob Latham    schedule 17.12.2014


Отговори (1)


Няма пряка връзка между eager/rendezvous и MPI_Send/Isend. Ако обаче сте под лимита за нетърпение, вашият MPI_Send вече не блокира. Ако искате да блокира независимо от това, можете да използвате MPI_Ssend.

Относно нетърпеливите ограничения:

MVAPICH2:
MV2_IBA_EAGER_THRESHOLD= < nbytes >
Intel MPI:
I_MPI_EAGER_THRESHOLD= < nbytes >
Open MPI:
--mca_btl_openib_eager_limit < nbytes >
--mca_btl_openib_rndv_eager_limit < nbytes >
Cray MPICH:
MPICH_GNI_MAX_EAGER_MSG_SIZE=<value>
person Victor Eijkhout    schedule 14.06.2018
comment
преносима опция за винаги използване на изпращане на рандеву е да предефинирате MPI_Send() във вашия код и да го извикате PMPI_Ssend() - person Gilles Gouaillardet; 15.06.2018