将数组片作为参数传递时的Fortran性能

将数组片作为参数传递时的Fortran性能,fortran,slice,fortran90,Fortran,Slice,Fortran90,我喜欢fortran的数组切片表示法(array(1:n)),但我想知道如果在不需要的时候使用它们,是否会影响性能 例如,考虑一下这个简单的快速排序代码(它可以工作,但显然没有注意选择一个好的轴心): 递归子例程快速排序(数组、大小) 实数,维度(:),意图(inout)::数组 整数,意图(in)::大小 整数::p 如果(大小>1),则 p=分区(数组,大小,1) 调用快速排序(数组(1:p-1),p-1) 调用快速排序(数组(p+1:size),size-p) 如果结束 结束子例程快速排序

我喜欢fortran的数组切片表示法(
array(1:n)
),但我想知道如果在不需要的时候使用它们,是否会影响性能

例如,考虑一下这个简单的快速排序代码(它可以工作,但显然没有注意选择一个好的轴心):

递归子例程快速排序(数组、大小) 实数,维度(:),意图(inout)::数组 整数,意图(in)::大小 整数::p 如果(大小>1),则 p=分区(数组,大小,1) 调用快速排序(数组(1:p-1),p-1) 调用快速排序(数组(p+1:size),size-p) 如果结束 结束子例程快速排序 函数分区(数组、大小、透视索引)结果(p) 实数,维度(:),意图(inout)::数组 整数,意图(in)::大小,数据透视索引 real::pivot 整数::i,p pivot=数组(pivotdex) 呼叫交换(数组(数据透视索引)、数组(大小)) p=1 i=1,尺寸为1吗 如果(数组(i) 我可以很容易地传递整个数组以及递归部分应该在哪里工作的索引,但是我喜欢这样的代码。然而,当我调用
快速排序(array(1:p-1),p-1)
时,它是生成一个临时数组来操作,还是只是生成一个浅引用结构或类似的东西?这是一个足够有效的解决方案吗

是相关的,但它看起来像是临时数组,因为它有跨步切片和显式大小的虚拟变量,所以我不会那么做,对吗?

您的子数组

  array(1:p-1)
是连续的,前提是
数组
是连续的

此外,还可以使用假定的形状数组伪参数

  real, dimension(:), intent(inout) :: array
不需要临时的。只传递假定形状数组的描述符。由于子数组是连续的,所以即使是带有
continuous
属性的假定大小、显式大小或假定大小伪参数也可以

  array(1:p-1)
是连续的,前提是
数组
是连续的

此外,还可以使用假定的形状数组伪参数

  real, dimension(:), intent(inout) :: array

不需要临时的。只传递假定形状数组的描述符。而且,由于子阵列是连续的,所以即使是假定大小、显式大小或带有
continuous
属性的假定大小伪参数也可以。

关于效率问题:是的,在大多数情况下,使用假定形状阵列和阵列切片确实是一个足够有效的解决方案

这涉及到一些开销。假定形状数组需要数组描述符(有时也称为“摄影向量”)。此数组描述符包含有关维度和步长的信息,设置它需要一些工作

带有假定形状伪参数的被调用过程中的代码必须同时考虑统一步幅(通常情况)和非统一步幅。某个地方的某个人可能想用somearray(1:100:3)的实际参数调用排序例程,因为他只想对数组的每三个元素进行排序。不寻常,但合法。不能依赖于unity stride的代码可能会有一些性能损失

话虽如此,编译器,特别是那些使用链接时间优化的编译器,现在在内联和/或剥离所有额外工作方面相当不错,并且倾向于克隆过程以实现特殊的速度


因此,作为一项规则,清晰度(和假定的形状阵列)应该获胜。请记住,在某些情况下,传递数组参数的老式方法可能会获得一些额外的效率。

关于效率问题:是的,在大多数情况下,使用假定形状的数组和数组切片确实是一个足够有效的解决方案

这涉及到一些开销。假定形状数组需要数组描述符(有时也称为“摄影向量”)。此数组描述符包含有关维度和步长的信息,设置它需要一些工作

带有假定形状伪参数的被调用过程中的代码必须同时考虑统一步幅(通常情况)和非统一步幅。某个地方的某个人可能想用somearray(1:100:3)的实际参数调用排序例程,因为他只想对数组的每三个元素进行排序。不寻常,但合法。不能依赖于unity stride的代码可能会有一些性能损失

话虽如此,编译器,特别是那些使用链接时间优化的编译器,现在在内联和/或剥离所有额外工作方面相当不错,并且倾向于克隆过程以实现特殊的速度


因此,通常,清晰性(和假定的形状数组)应该是成功的。请记住,在某些情况下,传递数组参数的老式方法可能会获得一些额外的效率。

非常好,谢谢!这就是我的想法,但我想确定一下,在互联网上找不到太多……太好了,谢谢!这就是我的想法,但我想确定一下,在互联网上找不到太多……有一条评论——为什么要单独传递尺寸?您还可以确定是否使用
大小
内部变量。对于问题来说,这不是必需的,但是在代码示例oops中没有定义newdex,
newdex
应该是
p
;我试图让这些名字更符合逻辑,但无法决定哪个更糟。你说得对,我想我本可以用
大小
,但我总是忘了。此外,调用该函数的数组更大,并且只在工作代码中填充了一部分,但是将一个切片传递给最外层的函数可以解决这个问题,而
分区
函数实际上不需要这样做