将数组传递给期望不同形状的子例程 [英] Passing an array to a subroutine that expects a different shape

查看:44
本文介绍了将数组传递给期望不同形状的子例程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一维工作数组

real(8), allocatable :: work(:)

传递给在二维数组上运行的子例程

which is passed to a subroutine that operates on a 2-dimensional array

pure subroutine f(work, dim1, dim2)
  real(8), intent(out) :: work(dim1, dim2)
  integer, intent(in) :: dim1, dim2
  ...

以下几种传递数组的方式有什么区别?

What is the difference in the following ways of passing the array?

call f(work, dim1, dim2)
call f(work(1), dim1, dim2)

它们是否相同,只是将指针传递给第一个数组元素,还是两个调用都有额外的开销?在现代的Fortran中,是否存在更优雅的方式来传递需要更改形状的数组,而无需显式传递尺寸,但又不影响性能?

Are they the same in that they just pass the pointer to the first array element or is there some extra overhead with either call? Are there more elegant ways in modern Fortran of passing an array whose shape needs to change, without passing the dimensions explicitly, but without taking a performance hit?

我知道上面的代码看起来像旧的Fortran,但是我发现它比在父子例程中声明二维数组并传递数组段 work(:dim1,:dim2)更快.,到 f .

I know the above looks like old Fortran but I've found it faster than declaring a two-dimensional array in the parent subroutine and passing an array section, work(:dim1,:dim2), to f.

推荐答案

两个示例语句都是序列关联的形式.实际参数指定一个数组元素序列,然后按数组元素顺序将其与哑元参数的元素相关联.

Both example statements are forms of sequence association. The actual argument specifies a sequence of array elements, that are then associated with the elements of the dummy argument in array element order.

如果将工作(在调用范围内)分配为非零大小且下限为1,则在实现上不太可能存在实际差异.

If work (in the calling scope) is allocated to non-zero size and has a lower bound of one, there is unlikely to be a practical difference in implementation.

在两种情况下,程序员都必须确保虚拟参数的大小必须小于或等于实际参数元素序列的大小.

In both cases, the programmer must ensure that the size of the dummy argument must be less than or equal to the size of the actual argument element sequence.

使用整个数组引用使读者(也许是编译器)更加清楚,作者的意图是传递数组元素序列,可能包含数组的所有元素.它还可以防止实际参数大小为零,或者下限值不是一个.

Using the whole array reference makes it clearer to readers (and perhaps the compiler) that it was the author's intent to pass an array element sequence, potentially including all the elements of the array. It also defends against the actual argument being zero size, or perhaps having a lower bound other than one.

当使用对特定元素的引用来指定数组元素序列时,作者的意图还远远不够清楚.

The author's intent is far less clear when a reference to a specific element is used to designate an array element sequence.

在这种特定情况下,由于实际参数是可分配的,因此编译器知道实际参数的元素序列将是连续的,并且它可以安排将哑参数与元素序列适当地关联.在其他情况下,假设如果实际参数本身是假定的形状参数,但没有连续属性,则编译器将不知道元素序列是连续的,并且可能必须在调用之前复制元素序列.这可能会对性能产生重大影响-这可能是您发现使用不连续的第2级数组部分作为实际参数的速度较慢的原因.

In this specific case, because the actual argument is allocatable the compiler knows that the element sequence of the actual argument will be contiguous, and it can arrange for the dummy argument to be associated with the element sequence appropriately. In other cases, say if the actual argument was itself an assumed shape argument without the contiguous attribute, the compiler does not know that the element sequence is contiguous, and it may have to make a copy of the element sequence ahead of the call. This can have material performance impact - it is probably the reason why you found using a non-contiguous rank two array section as an actual argument to be slower.

这篇关于将数组传递给期望不同形状的子例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆