小编hol*_*oly的帖子

具有SysV共享内存的异步MPI

我们有一个庞大的Fortran/MPI代码库,它使用节点上的system-V共享内存段.我们运行在具有32个处理器的胖节点上,但只有2或4个NIC,每个CPU的内存相对较少; 所以我们的想法是建立一个共享内存段,每个CPU在其上执行计算(在其SMP数组块中).然后,MPI用于处理节点间通信,但仅用于SMP组中的主节点.该程序是双缓冲的,并且对我们很有效.

当我们决定切换到异步通信时,出现了一些延迟隐藏的问题.由于节点上只有几个CPU通过MPI进行通信,但所有CPU都看到了接收到的阵列(通过共享内存),CPU不知道通信CPU何时完成,除非我们制定了某种障碍,并且那么为什么要进行异步通信呢?

理想的假设解决方案是将请求标记放在SMP段中,并在需要知道的CPU上运行mpi_request_get_status.当然,请求标记只在通信CPU上注册,所以它不起作用!另一个提议的可能性是在通信线程上分支线程并使用它在循环中运行mpi_request_get_status,并在共享内存段中使用flag参数,因此所有其他映像都可以看到.不幸的是,这也不是一种选择,因为我们不能使用线程库.

我们提出的唯一可行的选择似乎有效,但感觉就像一个肮脏的黑客.我们在接收缓冲区的上限地址中放置了一个不可能的值,这样一旦mpi_irecv完成,该值就会改变,因此每个CPU都知道它何时可以安全地使用缓冲区.这可以吗?如果可以保证MPI实现连续传输数据,它似乎只能可靠地工作.这几乎听起来令人信服,因为我们已经在Fortran中编写了这个东西,因此我们的数组是连续的; 我会想象访问也是如此.

有什么想法吗?

谢谢,乔利

这是我正在做的事情的伪代码模板.没有把代码作为参考在家里,所以我希望我没有忘记任何关键的东西,但我会确保当我回到办公室时......

pseudo(array_arg1(:,:), array_arg2(:,:)...)

  integer,      parameter : num_buffers=2
  Complex64bit, smp       : buffer(:,:,num_buffers)
  integer                 : prev_node, next_node
  integer                 : send_tag(num_buffers), recv_tag(num_buffers)
  integer                 : current, next
  integer                 : num_nodes

  boolean                 : do_comms
  boolean,      smp       : safe(num_buffers)
  boolean,      smp       : calc_complete(num_cores_on_node,num_buffers)

  allocate_arrays(...)

  work_out_neighbours(prev_node,next_node)

  am_i_a_slave(do_comms)

  setup_ipc(buffer,...)

  setup_ipc(safe,...)

  setup_ipc(calc_complete,...)

  current = 1
  next = mod(current,num_buffers)+1

  safe=true

  calc_complete=false

  work_out_num_nodes_in_ring(num_nodes)

  do i=1,num_nodes

    if(do_comms)
      check_all_tags_and_set_safe_flags(send_tag, recv_tag, safe) # just in case anything else has finished.
      check_tags_and_wait_if_need_be(current, send_tag, recv_tag)
      safe(current)=true
    else
      wait_until_true(safe(current)) …
Run Code Online (Sandbox Code Playgroud)

mpi shared-memory fortran90

5
推荐指数
1
解决办法
285
查看次数

标签 统计

fortran90 ×1

mpi ×1

shared-memory ×1