Односторонняя связь с MPI-2

Рассмотрим следующий фрагмент кода OpenMP, который передает частные данные между двумя потоками с использованием промежуточной общей переменной.

#pragma omp parallel shared(x) private(a,b)
{
    ...
   a = somefunction(b);
   if (omp_get_thread_num() == 0) {
      x = a;
   }
}
#pragma omp parallel shared(x) private(a,b)
{
  if (omp_get_thread_num() == 1) {
    a = x;
  }
  b = anotherfunction(a);
  ...
}

Мне (в псевдокоде) нужно было бы передавать частные данные из одного процесса в другой, используя одностороннюю библиотеку передачи сообщений. Любые идеи?


person Manolete    schedule 07.05.2011    source источник
comment
ваши примеры кода неверны, это две последовательные параллельные области. Чтобы поделиться датой, используйте память (с блокировками/мьютексами), а не MPI   -  person Anycorn    schedule 07.05.2011
comment
В любом случае, они не являются последовательными, но эта идея состоит в том, чтобы достичь той же функциональности с помощью односторонней связи, а не с помощью блокировок.   -  person Manolete    schedule 07.05.2011
comment
Ваш код верен только из-за неявного барьера памяти, связанного с соединением в конце параллельной области. Если вы объединяете параллельные регионы, ваш код нуждается в четком определении границы/сброса. А так как соединение также подразумевает наличие барьера, в этом коде все равно нет смысла. Вы уже получите совместное использование переменных и синхронизацию бесплатно. См. реализацию Parallel Research Kernels synch_p2p OpenMP для правильного примера передачи сообщений в OpenMP.   -  person Jeff Hammond    schedule 07.09.2015


Ответы (1)


Это возможно, но здесь задействовано гораздо больше «строительных лесов» — в конце концов, вы передаете данные между потенциально совершенно разными компьютерами.

Координация для такого рода вещей осуществляется между окнами данных, которые доступны из других процессоров, и операциями блокировки/разблокировки, которые координируют доступ к этим данным. Блокировки на самом деле не являются блокировками в смысле мьютексов, но они больше похожи на точки синхронизации, координирующие доступ данных к окну.

У меня сейчас нет времени объяснять это так подробно, как хотелось бы, но ниже приведен пример использования MPI2 для выполнения чего-то вроде пометки разделяемой памяти в системе, не имеющей разделяемой памяти:

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

int main(int argc, char** argv)
{
    int rank, size, *a, geta;
    int x;
    int ierr;
    MPI_Win win;
    const int RCVR=0;
    const int SENDER=1;

    ierr = MPI_Init(&argc, &argv);
    ierr |= MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    ierr |= MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (ierr) {
        fprintf(stderr,"Error initializing MPI library; failing.\n");
        exit(-1);
    }

    if (rank == RCVR) {
        MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &a);
        *a = 0;
    } else {
        a = NULL;
    }

    MPI_Win_create(a, 1, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);

    if (rank == SENDER) {
        /* Lock recievers window */
        MPI_Win_lock(MPI_LOCK_EXCLUSIVE, RCVR, 0, win);

        x = 5;

        /* put 1 int (from &x) to 1 int rank RCVR, at address 0 in window "win"*/
        MPI_Put(&x, 1, MPI_INT, RCVR, 0, 1, MPI_INT, win);

        /* Unlock */
        MPI_Win_unlock(0, win);
        printf("%d: My job here is done.\n", rank);
    }

    if (rank == RCVR) {
        for (;;) {
            MPI_Win_lock(MPI_LOCK_EXCLUSIVE, RCVR, 0, win);
            MPI_Get(&geta, 1, MPI_INT, RCVR, 0, 1, MPI_INT, win);
            MPI_Win_unlock(0, win);

            if (geta == 0) {
                printf("%d: a still zero; sleeping.\n",rank);
                sleep(2);
            } else
                break;
        }
        printf("%d: a now %d!\n",rank,geta);
        printf("a = %d\n", *a);
    MPI_Win_free(&win);
    if (rank == RCVR) MPI_Free_mem(a);
    MPI_Finalize();

    return 0;
}
person Jonathan Dursi    schedule 07.05.2011