MPI 3 конфликты между общей памятью и кешем - PullRequest
3 голосов
/ 18 марта 2020

При использовании разделяемой памяти MPI 3 мне пришло в голову, что запись в смежные позиции памяти окна совместно используемой памяти одновременно для разных задач, по-видимому, не работает.

Я догадывался, что MPI игнорирует возможные конфликты кэша, и теперь У меня вопрос: верно ли это, и MPI действительно не заботится о когерентности кэша, или это извращенная реализация, или есть ли совершенно другое объяснение этому поведению?

Это минимальный пример где в Фортране одновременная запись по разным адресам в окне общей памяти вызывает конфликт (протестировано с Intel MPI 2017, 2018, 2019 и GNU OpenMPI 3).

program testAlloc
use mpi
use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_f_pointer
implicit none

integer :: ierr
integer :: window
integer(kind=MPI_Address_kind) :: wsize
type(c_ptr) :: baseptr
integer, pointer :: f_ptr
integer :: comm_rank

call MPI_Init(ierr)

! Each processor allocates one entry
wsize = 1
call MPI_WIN_ALLOCATE_SHARED(wsize,4,MPI_INFO_NULL,MPI_COMM_WORLD,baseptr,window,ierr)

! Convert to a fortran pointer
call c_f_pointer(baseptr, f_ptr)

! Now, assign some value simultaneously
f_ptr = 4

! For output, get the mpi rank
call mpi_comm_rank(MPI_COMM_WORLD, comm_rank, ierr)

! Output the assigned value - only one task reports 4, the others report junk
print *, "On task", comm_rank, "value is", f_ptr

call MPI_Win_free(window, ierr)
call MPI_Finalize(ierr)
end program

Любопытно, что одна и та же программа в C, кажется, работает как задумано, что приводит к вопросу, если что-то не так с реализацией на Фортране, или программе C просто повезло (протестировано с теми же библиотеками MPI)

#include <mpi.h>
#include <stdio.h>

int main(int argc, char *argv[]){
  MPI_Init(&argc, &argv);
  // Allocate a single resource per task
  MPI_Aint wsize = 1;

  // Do a shared allocation
  int *resource;
  MPI_Win window;
  MPI_Win_allocate_shared(wsize, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &resource, &window);

  // For output clarification, get the mpi rank
  int comm_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);

  // Assign some value
  *resource = 4;  

  // Tell us the value - this seems to work
  printf("On task %d the value is %d\n",comm_rank,*resource);

  MPI_Win_free(&window);
  MPI_Finalize();
}

1 Ответ

2 голосов
/ 19 марта 2020

Из стандарта MPI 3.1 (глава 11.2.3, с. 407)

MPI_WIN_ALLOCATE_SHARED (размер, disp_unit, информация, comm, baseptr, win)

размер IN размера локального окно в байтах (неотрицательное целое число)

Обратите внимание, что размер окна указан в байтах , а не в количестве единиц.

Поэтому все, что вам нужно, это используйте

wsize = 4

в Фортране (при условии, что ваш INTEGER размер действительно 4) и

wsize = sizeof(int);

в C

FWIW

  • , даже если версия C в большинстве случаев дает ожидаемый результат, она также неверна, и я могу это доказать, запустив программу под отладчиком.
  • обычно говоря, вам, возможно, придется объявить volatile int * resource; в C, чтобы компилятор не выполнил некоторые оптимизации, которые могут повлиять на поведение вашего приложения (а здесь это не нужно).
...