【问题标题】:Passing an array to a subroutine将数组传递给子程序
【发布时间】:2015-09-02 11:45:07
【问题描述】:

当我将数组传递给子例程时,它是移动整个数组还是仅移动指向内存路​​径的指针? 我的问题看起来像:

program run
   real,dimension :: p(200,200,200)
   integer :: i

   do i=0,10000000
      call sub_p(p)
   enddo
end

subroutine sub_p(rhs)
   real,dimension :: rhs(200,200,200)

   ...

end

因为如果传递了整个数组,运行时可能需要更长的时间?

@弗拉基米尔: 所以在上面的代码中传递了一个指针,但是如果代码如下所示,则复制数组?:

program run
   real,dimension :: p(200,200,200)
   integer,parameter :: imax = 198
   integer,parameter :: jmax = 198
   integer,parameter :: kmax = 198
   integer :: ib,ie,jb,je,kb,ke
   integer :: i

   ib=1; ie=ib+imax
   jb=1; je=jb+jmax
   kb=1; ke=kb+kmax

   do i=0,10000000
      call sub_p(p(ib:ie,jb:je,kb:ke))
   enddo
end

subroutine sub_p(rhs)
   integer,parameter :: imax = 198
   integer,parameter :: jmax = 198
   integer,parameter :: kmax = 198
   real,dimension :: rhs(imax,jmax,kmax)

   ...

end

我说的对吗?

【问题讨论】:

  • 这部分取决于子例程的定义方式。 [例如,dummy 参数是否具有value 属性。]
  • @francescalus 代码是用 F90 标准写的,还有值选项吗?
  • 不在 f90 或 95 中,但自 2003 年以来一直是
  • 默认情况下,fortran 通过引用传递参数。所以在你的情况下,没有副本。
  • @chi86 您可以通过附加 -fcheck-array-temporaries 或 -fcheck=array-temps (对于 gfortran)等选项来确认是否创建了副本。我想 ifort 也会有类似的选择。

标签: arrays pointers fortran subroutine


【解决方案1】:

是的,如果接口是隐式的或者虚拟参数是一个显式的形状数组,正如你所拥有的,则传递一个指针。 (标准没有明确说明,但实际上它是唯一可能的实现。

但它可以是指向副本的指针!如果数组不连续并且接口是隐式的,就会有一个副本!

在你的情况下:

没有副本:

call sub_p(p)

需要一份副本:

call similar_sub(p(1,:,:))

【讨论】:

  • 好的,我明白了。我在我的问题中添加了另一个示例,你会看吗?
  • 是的,另一个例子需要一个副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2021-05-23
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
相关资源
最近更新 更多