Performance 带掩码和do循环的和的性能

Performance 带掩码和do循环的和的性能,performance,sum,fortran,Performance,Sum,Fortran,带掩码的内在函数sum是否比老式do循环慢 我正在用Fortran 90编写一个金融应用程序。 有一个用户定义的类型,它将一个 单张债券,如账面价值、时间价值、利率,属于原子型整数、实数和字符 type(portfolioElementType) real(8) :: timeValue real(8) :: bookValue real(8) :: maturityInYears + many, many more end type 整个投资组合由一个2维矩阵

带掩码的内在函数
sum
是否比老式do循环慢

我正在用Fortran 90编写一个金融应用程序。 有一个用户定义的类型,它将一个 单张债券,如账面价值、时间价值、利率,属于原子型整数、实数和字符

type(portfolioElementType)
    real(8) :: timeValue
    real(8) :: bookValue
    real(8) :: maturityInYears
    + many, many more
end type
整个投资组合由一个2维矩阵组成,其中包含3000乘以10个元素的类型
portfolioElementType

type(portfolioElementType), dimension(:,:), pointer :: portfolio
allocate(portfolio(1:3000,1:10))
我想将投资组合按到期日(年)累加。在SQL中,可以将其称为GROUPBY语句

目前它是由

do bond = 1 to numberOfBonds
    do part = 1 to numberOfParts
        if (portfolio(bond,part)%maturity .eq. 10) then
            sum10Years = sum10Years + portfolio(bond,part)%bookValue
        end if
    end do 
end do
出于纯粹的美学原因,我更愿意通过以下方式实现:

sum10 = sum(portfolio%bookValue, mask = portfolio%maturity .eq. 10)
Booth选项给出了相同的结果,但求和方法似乎比do循环慢。这让我感到惊讶,因为求和大约30000个元素 应该几乎不费吹灰之力吗

我的假设是,用户定义的“大型”类型正在减慢速度。 我不知道Fortran如何处理它的内存结构,但我猜 “bookValues”在内存中彼此“遥远”吗

您认为与用户定义的“大”矩阵数据结构相比,我使用“大”用户定义数据结构的矩阵是否可取

portfolio(a,b)%bookValue versus 
bigPortfolio%bookValue(a,b)


这取决于优化级别、编译器、它的选项、您的机器等等。。。但总的来说,根据我的经验,编译器可以比“复杂”代码更好地优化“简单代码”。此外,OOP通常需要大量的(反)引用,这会降低代码的速度。求和30000个元素几乎应该很容易,但读取30000个非连续内存位置可能不如读取30000个连续内存位置快(正如OP所建议的)。这看起来像是一个在结构数组和数组结构之间进行选择的经典案例。还有一件事,尽管它不太可能对性能产生明显的影响。。。除非你真的需要指针,否则我现在会使用可分配的数组。@Ratilius,当你说“求和法似乎比do循环慢”时,你说的时差顺序是什么?你是怎么计时的?为了得出这个结论,你平均运行了多少次?我使用了gprof,而使用和的函数是最慢的函数之一。我使用gcc和o3进行编译。运行时间从73秒上升到85秒(walltime时钟)。所讨论的代码片段在大型程序中只是一个很小的构建块,可能占运行时的1%,因为它不常被调用。如果我能模仿这种行为,我将构建一个沙盒示例并发布它。
type(bigPortfolio)
   real(8), dimension(1:3000,1:10), pointer :: bookValue
   ...many more matrices
end type