我在使用Fortran时遇到了以下情况
可选属性
并试图找出最佳(性能方面)解决方案。
如果有人能给我一个好的提示,我会很高兴。
请注意,我对我能获得的每一个性能提升都很感兴趣,因为我的阵列很大,循环的数量和循环甚至更大。
我的情况是,计算要么使用可选参数完成,要么在不存在的情况下,在其位置使用另一个数组。
subroutine compute(tmat,av,av2)
implicit none
complex,intent(out) :: tmat(:)
complex,intent(in) :: av(:)
complex,intent(in),optional :: av2(:)
if(present(av2)) then
tmat = av *av2
else
tmat = av *av
end if
end subroutine compute_transition_matrices_bosonic
在这个简单的例子中,上面的解决方案很好。然而,我的真实代码要复杂得多。
这意味着例程的内部块可能非常大(数百行),最重要的是包含许多嵌套循环。
可以想象如下:
if(present(av2)) then
tmat = "function"(av,av2)
else
tmat = "function"(av,av)
end if
其中“function”代表许多操作和循环(因此是“”)。重点是,这两种情况下的操作相同
if语句,因此我需要编写两次代码。另一个解决方案是检查
av2
出现在
这会产生一些开销,因为这种检查会非常频繁地进行。
我想知道是否有更聪明的办法来解决这个问题。首先,可以考虑使用临时变量
complex, :: phi_tmp(:)
if(present(av2)) then
phi_tmp = av2
else
phi_tmp = av
end if
tmat = "function"(av,phi_tmp)
这通常在使用可选参数时进行。但这将复制数据,在我的情况下,这是一个非常庞大的数组。
因此,我想使用指针
complex,intent(in),target :: av(:)
complex,intent(in),optional,target :: av2(:)
complex,pointer :: phi_tmp(:)
if(present(av2)) then
phi_tmp => av2
else
phi_tmp => av
end if
tmat = "function"(av,phi_tmp)
但这需要
TARGET
的属性
av
和
平均值2
。这里我不确定这是否会导致性能下降,因为编译器
不能再假设
平均值
和
平均值2
在其优化过程中没有别名,即使这里两者都有
INTENT(IN)
属性
从而不会出现混叠问题。此外,如果调用例程时输入中的参数
没有
目标
属性(这将编译并运行!)
有人对这些问题有经验吗?
是否有“标准”解决方案?(我找不到)
最终的最佳解决方案是什么?