我有一个1维工作数组
real(8), allocatable :: work(:)
传递给在二维数组上运行的子程序
pure subroutine f(work, dim1, dim2)
real(8), intent(out) :: work(dim1, dim2)
integer, intent(in) :: dim1, dim2
...
以下传递数组的方法有何不同?
call f(work, dim1, dim2)
call f(work(1), dim1, dim2)
它们是否相同,因为它们只是将指针传递给第一个数组元素,或者是否有一些额外的开销与任何一个调用?在现代Fortran中是否有更优雅的方式来传递一个阵形需要改变的阵列,而不是明确地传递尺寸,但是没有受到性能影响?
我知道上面看起来像旧的Fortran,但我发现它比在父子程序中声明一个二维数组并将数组部分work(:dim1,:dim2)
传递给f
更快。
答案 0 :(得分:3)
两个示例语句都是序列关联的形式。实际参数指定一系列数组元素,然后以数组元素顺序与伪参数的元素相关联。
如果工作(在调用范围内)被分配到非零大小并且下限为1,则实现中不太可能存在实际差异。
在这两种情况下,程序员必须确保伪参数的大小必须小于或等于实际参数元素序列的大小。
使用整个数组引用使得读者(以及编译器)更清楚它是作者的意图传递数组元素序列,可能包括数组的所有元素。它还防止实际参数为零大小,或者可能具有除一个以外的下限。
当使用对特定元素的引用来指定数组元素序列时,作者的意图就不那么明确了。
在这种特定情况下,因为实际参数是可分配的,所以编译器知道实际参数的元素序列将是连续的,并且它可以安排伪参数适当地与元素序列相关联。在其他情况下,假设实际参数本身是没有连续属性的假定形状参数,编译器不知道元素序列是连续的,并且它可能必须在调用之前复制元素序列。这可能会对材料性能产生影响 - 这可能是您发现使用非连续的二级数组部分作为实际参数的速度较慢的原因。