2017-01-23 27 views
1

我有个1维工作阵列传递数组给需要不同形状的子程序

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

其被传递到一个2维阵列

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

在某种意义上,这里有两个完全不同的问题。 [1]](http://stackoverflow.com/q/25000321)'work'和'work(1)'.as参数有什么区别? [2]](http://stackoverflow.com/q/24472907)如何将一个与哑元相关联的形状数组作为另一个形状? – francescalus

+0

对于你的最后一点,如果'work'是一个rank-2数组,那么如果你将'work'作为一个整体数组而不是数组部分'work(:dim1,:dim2)',那么会发生什么? – francescalus

+0

谢谢。在子程序内部,我正在做一些事情,比如用'work(:dim1,:dim2)'调用'dgemm''作为参数之一。如果在调用作用域中将'work'声明为二维数组并且传递了完整数组,则这将导致自动创建一个临时数组。重点是每个调用的维度可能不同,但我只分配一次工作空间。 –

回答

3

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

如果工作(在呼叫范围)被分配给非零尺寸并具有较低的一个约束,有不太可能在执行实际的差异。

在这两种情况下,程序员必须保证伪参数的尺寸必须小于或等于该实际参数元素序列的大小。

使用整个阵列参考使得它更清晰的读者(或许还有编译器),这是作者的意图传递数组元素序列,潜在地包括该阵列中的所有元素。它也抵御实际的论据是零大小,或者可能有一个以外的下限。

作者的意图是远不太清楚,当一个特定的元素的引用是用来指定的数组元素序列。

在此特定情况下,因为实际的参数是可分配的编译器知道实际的参数的元件序列将是连续的,并且它可以安排为伪参数要具有适当的元件序列相关联。在其他情况下,如果实际参数本身是没有连续属性的假定形状参数,则编译器不知道该元素序列是连续的,并且可能必须在调用之前复制元素序列。这可能会对材料性能产生影响 - 这可能就是为什么您发现使用非连续的rank 2数组部分作为实际参数变慢的原因。

相关问题