问题描述
我首先要检查这段代码。检查后,我现在想知道是否可以优化。特别是,提出的问题是:
“预先初始化大型计算的所有单个成员而不是直接在其中计算它们(即 sqrt() )会更好吗?”
换句话说,在计算本身执行计算时,内存分配与 cpu 时间之间是否存在权衡?
这是代码片段(编辑):
do id=1,3
BF(idx1,idx2,idx3) = BF(idx1,idx3) +&
! i-j,i-k
2*bsa_wind_coeff(ilib,4+id,inode)*bsa_wind_coeff(jlib,1+id,jnode)*bsa_wind_coeff(klib,knode)* &
(nodCorr(id,p1)* sqrt(SU(i1,id,inode)*SU(i1,jnode))) * (nodCorr(id,p2)* sqrt(SU(i2,inode)*SU(i2,knode)) )+&
! i-j,j-k
2*bsa_wind_coeff(ilib,p1)* sqrt(SU12(id,inode)*SU12(id,p3)* sqrt(SU(i2,jnode)*SU(i2,knode)) )+&
! i-k,p2)* sqrt(SU12(id,knode))) * (nodCorr(id,p3)* sqrt(SU(i1,jnode)*SU(i1,knode)) )
enddo
! dir 1-2
BF(idx1,idx3) +&
! i-k,i-j
bsa_wind_coeff(ilib,8,3,2,knode)* &
(nodCorr(1,p2)* sqrt( SU(i2,1,knode) )) * (nodCorr(2,p1)* sqrt( SU(i1,jnode) ) )+&
! i-j,j-k
bsa_wind_coeff(ilib,p2)* sqrt( SU12(1,inode)*SU12(1,jnode) )) * (nodCorr(2,p3)* sqrt( SU(i2,knode) ) )+&
! j-k,i-k
bsa_wind_coeff(ilib,p3)* sqrt( SU(i1,p2)* sqrt( SU12(2,inode)*SU12(2,knode) ) )+&
! i-j,p1)* sqrt( SU12(2,jnode) ) )+&
! i-k,knode) ) )
! dir 1-3
BF(idx1,9,4,knode) )) * (nodCorr(3,jnode) )) * (nodCorr(3,p2)* sqrt( SU12(3,inode)*SU12(3,p1)* sqrt( SU12(3,knode) ) )
! dir 2-3
BF(idx1,idx3) +&
bsa_wind_coeff(ilib,10,knode)* &
(nodCorr(2,jnode) ) )+&
bsa_wind_coeff(ilib,knode) ) )+&
bsa_wind_coeff(ilib,knode) ) )
一些注意事项:
bsa_wind_coeffs 是一个通用变量(在模块中声明),而代码片段中存在的所有其他变量都是直接传递的(即我假设在本地创建了一个副本)。在过程本身内,索引ilib、jlib、klib、inode、jnode、knode 是循环的。此计算在外部过程中被多次调用。
编辑: 这里的所有变量都是静态,因为它们被计算一次(在调用此过程之前),然后只是根据一些索引值进行遍历,如您所见。也就是说,在每次调用时,都会传递相同的数组。
解决方法
在评论中你说你想要一个“概念性”的答案,关于什么时候预计算比不预计算快。
不幸的是,出于以下几个原因,对两种方法中哪一种更好进行静态分析通常很困难。首先,优化编译器非常聪明,在幕后做了很多相当不可预测的事情。其次,外部变量很多,编译器、cpu、内存等细节都会改变结果。
“这两种算法中哪一种更快”这个问题的答案通常是“两者都试试看”。您至少应该为代码计时,但使用分析工具是理想的选择。分析工具不仅会告诉您不同方法需要多长时间,它还有助于缩小两种方法中花费最多时间的部分。这让您知道应该优化代码的哪些部分以获得最佳结果。