【问题标题】:Fortran/MPI non-blocking send of non-persistent data非持久数据的 Fortran/MPI 非阻塞发送
【发布时间】:2012-11-29 03:24:49
【问题描述】:

考虑以下几点:

subroutine send_to_friend(a,b,c,request)
  implicit none
  include 'mpif.h'  !use mpi if you've built the mpif90 bindings...

  real a,b,c
  real buff(3)
  integer tag,dest,ierr,request

  tag = 50
  dest = 0

  buff(1) = a
  buff(2) = b
  buff(3) = c
  call MPI_Isend(buff,3,MPI_REAL,dest,tag,MPI_COMM_WORLD,request,ierr)
return
end subroutine send_to_friend

这可能不起作用,因为buff 将被放入堆栈(无论如何,大多数现代编译器),但只要子例程退出,它就会被清除干净。分配数组也无济于事,因为根据here(第 10 节),当您退出过程时,分配的数组会自动解除分配——在 C 中,这将是内存泄漏(也很糟糕)。做这样的事情的正确方法是什么?我应该使用save 属性声明数组吗? (static 在 C 中)。这种设计一开始就存在缺陷吗?

【问题讨论】:

  • 是的,我很想说设计本身就有问题。即使使用save,如果您快速连续两次调用此子例程会发生什么?您可以将MPI_Bsend 与“足够”的用户定义缓冲区空间一起使用,并管理缓冲区 MPI 的问题,但 Buffered Sends Are Evil
  • @JonathanDursi -- 这就是您返回 request 的原因 -- 以确保在您再次调用之前已发送数据。你应该怎么做这样的事情?当前进程在将数据发送到0 时有很多事情要做......如果0 太忙而无法立即接收消息,我不想等待......不是全部isend 的目的是什么?
  • 如果您必须手动处理检查以前的请求以了解调用此子例程是否安全,那么我就是看不到此子例程的意义。如果您必须做一堆低级的事情才能安全地调用这个子例程,那么您并没有真正抽象出任何东西。也许你已经在你的代码中得到了更高层次的覆盖,但是仅仅看到这个例程就很难说出来。如果你真的想这样做,我只是建议使用 bsend(注意:不是 ibsend,出于同样的原因)或者传递一个缓冲区并让它安全地处理缓冲。
  • 让我尝试更连贯地重写该评论;现在,即使使用save,临时缓冲区的安全处理是高层代码(调用前检查请求)和低层代码(将缓冲区填满数据)的责任)。这很尴尬且容易出错。我的建议是在调用代码中完成所有缓冲区处理(分配一个缓冲区,填充它,并将其传递给例程)或全部在较低级别的代码中(使用 Bsend 或您自己的缓冲区处理代码),只是不是两者。
  • @JonathanDursi -- 我的用例实际上比这更复杂。要发送(接收)的数据位于公共块中,这意味着我需要在调用过程中包含这些公共块——但这可能会引入命名空间冲突等。(注意,我无法控制那些设计决策)。我还希望能够从代码中的至少 2 个位置执行此操作,因此封装它似乎是个好主意。最后,request 都可以在本地处理(使用save)。第一次进入你不使用的功能MPI_Wait,每隔一次你都会这样做。

标签: c fortran mpi


【解决方案1】:

SAVE 应该没问题(最好与 allocatable 结合使用),前提是您没有遇到其他问题,这需要 Fortran 通过 copy-in copy-out 传递数组,它必须通过引用来完成(做不要尝试使用非阻塞 MPI 发送非连续数据)。

如果您在例程中有save 变量,也不要尝试从更多线程运行它,如果您结合了 MPI/OpenMP。

【讨论】:

  • 在 OpenMP 中以只读方式使用堆变量不安全,还是我的误解? (无论如何,我没有使用 OpenMP,所以这只是学术好奇心)。另外,为什么说最好与allocatable结合使用? (我想过,但后来我需要检查它是否已分配,这似乎有点乱)
  • 因为自动数组是不可能的,所以编译时间常数对小东西有好处,而指针会损害性能(不是在简单的情况下)。
  • Ad OpenMP:我只是想指出静态数组可能会导致程序是非线程安全的。当然,在每个线程模型中都有特定的方法可以克服这一点。
猜你喜欢
  • 2012-08-24
  • 2011-05-25
  • 2021-12-30
  • 2014-08-15
  • 2013-03-07
  • 1970-01-01
  • 2015-12-09
  • 2012-02-21
  • 2017-02-09
相关资源
最近更新 更多