将数组片作为参数传递时的Fortran性能
我喜欢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) 如果结束 结束子例程快速排序
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
;我试图让这些名字更符合逻辑,但无法决定哪个更糟。你说得对,我想我本可以用大小,但我总是忘了。此外,调用该函数的数组更大,并且只在工作代码中填充了一部分,但是将一个切片传递给最外层的函数可以解决这个问题,而分区
函数实际上不需要这样做