Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Fortran/MPI非阻塞发送非持久性数据_C_Fortran_Mpi - Fatal编程技术网

C Fortran/MPI非阻塞发送非持久性数据

C Fortran/MPI非阻塞发送非持久性数据,c,fortran,mpi,C,Fortran,Mpi,考虑以下几点: 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 bu

考虑以下几点:

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
将被放在堆栈上(无论如何,大多数现代编译器都是如此),但只要子例程退出,就会将其清除。分配数组也无济于事,因为根据(第10节),当您退出该过程时,分配的数组会自动解除分配——在C中,这将是内存泄漏(同样糟糕)。这样做的正确方法是什么?我应该用
save
属性声明数组吗?(
静态
在C中)。这种设计从一开始就有缺陷吗?

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


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

在OpenMP中将堆变量作为只读变量使用是否安全,或者这是我的误解?(无论如何,我没有使用OpenMP,所以这只是出于学术好奇心)。还有,为什么你说最好与allocatable结合呢?(我考虑过这个问题,但是我需要检查它是否被分配了,这似乎有点混乱)因为自动数组是不可能的,编译时常量对于小事情是好的,指针可能会损害性能(不是在简单的情况下)。Ad OpenMP:我只想指出静态数组可能会导致过程是非线程安全的。当然,在每个线程模型中都有克服这种问题的具体方法;即使使用
save
快速连续调用此子例程两次会发生什么?您可以使用“足够”的用户定义的缓冲区空间,并确保管理缓冲区MPI的问题,但是@JonathanDursi——这就是为什么您返回
请求
——以确保在再次调用之前已发送数据。你还能怎么做这样的事?当前进程在将数据发送到
0
时有很多事情要做…如果
0
太忙而无法立即接收消息,我不想等待。。。这难道不是
isend
的全部目的吗?如果您必须手动处理检查以前的请求,以了解调用此子例程是否安全,那么我不明白此子例程的意义。如果为了能够安全地调用这个子例程,您必须做一些低级的工作,那么您并没有真正抽象出任何东西。也许您已经在代码的更高层次上涵盖了这一点,但仅仅看到这个例程很难判断。如果你真的想这么做,我建议使用bsend(注意:不是ibsend,出于同样的原因),或者给它传递一个缓冲区,让它安全地处理缓冲;现在,即使使用
save
,临时缓冲区的安全处理也是高级代码(调用前检查请求)和低级代码(将缓冲区填满数据)的责任。这既尴尬又容易出错。我的建议是在调用代码中完成所有缓冲区处理(分配缓冲区、填充缓冲区并将其传递给例程)或在较低级别的代码中完成所有缓冲区处理(使用Bsend或您自己的缓冲区处理代码),但不能两者兼而有之。@JonathanDursi——我的用例实际上比这更复杂。要发送(接收)的数据位于公共块中,这意味着我需要在调用过程中包含这些公共块——但这可能会导致名称空间冲突等(注意,我无法控制这些设计决策)。我还希望能够在代码中至少从两个位置执行此操作,因此封装它似乎是一个好主意。最后,
请求
都可以在本地处理(使用
保存
)。第一次输入函数时,您不必等待MPI\u,每隔一次。