Заставить MPI_Send использовать протокол ожидания или рандевууза

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

Мы раньше не работали с MPI и думали, что может быть способ «выбрать» между двумя протоколами. Поискав в гугле информацию о том, как это сделать, я нашел (где-то не помню), что есть предел нетерпения. Я читал, что он задается реализацией 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)


Прямой связи между нетерпеливым/рандеву и 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