【问题标题】:MPI 3 shared memory and cache conflictsMPI 3 共享内存和缓存冲突
【发布时间】:2020-06-29 11:00:53
【问题描述】:

在使用 MPI 3 共享内存时,我想到在不同任务上同时写入共享内存窗口的相邻内存位置似乎不起作用。

我猜 MPI 忽略了可能的缓存冲突,现在我的问题是这是否正确并且 MPI 确实不关心缓存一致性,或者这是否是实现的一个怪癖,或者是否有完全不同的解释行为?

这是一个最小示例,在 Fortran 中,同时写入共享内存窗口中的不同地址会导致冲突(使用 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 中的同一个程序似乎确实按预期工作,这导致了一个问题,即 Fortran 实现是否有问题,或者 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();
}

【问题讨论】:

  • 恐怕你的C程序不正确。应该是int *resource;,然后是*resource = 4;,然后是printf(..., *resource);
  • @GillesGouaillardet 很好,谢谢。我更新了代码。但是,行为没有改变,所以我的问题保持不变。
  • 您没有正确使用MPI_Win_allocate_shared()baseptr 参数(正确的用法一开始可能看起来有悖常理)。
  • 在 Fortran 中,如果您声明 integer, pointer :: f_ptr(:) 并设置/打印 f_ptr(1) 会怎样
  • @GillesGouaillardet 这产生了相同的结果,但现在我想知道这个例子是否有问题。让我三重检查

标签: mpi shared-memory


【解决方案1】:

来自 MPI 3.1 标准(第 11.2.3 章第 407 页)

MPI_WIN_ALLOCATE_SHARED(size, disp_unit, info, comm, baseptr, win)

IN size 本地窗口大小,以字节为单位(非负整数)

请注意,窗口大小以字节为单位,而不是单位数。

所以你只需要使用

wsize = 4

在 Fortran 中(假设您的 INTEGER 大小确实是 4)和

wsize = sizeof(int);

C

FWIW

  • 即使C 版本在大多数情况下似乎都给出了预期的结果,但它也是不正确的,我可以通过在调试器下的程序下运行来证明这一点。
  • 一般来说,您可能必须在 C 中声明 volatile int * resource; 以防止编译器执行一些可能影响您的应用行为的优化(这里不需要这样做)。

【讨论】:

猜你喜欢
  • 2011-05-22
  • 2015-04-07
  • 2021-01-19
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 2017-06-30
  • 1970-01-01
相关资源
最近更新 更多