首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么启动gfortran编译器优化时matmul会变慢?

为什么启动gfortran编译器优化时matmul会变慢?
EN

Stack Overflow用户
提问于 2021-03-17 22:30:10
回答 1查看 344关注 0票数 3

如果我在Mac上使用gfortran (Homebrew GCC 8.2.0)来编译下面的简单程序,而不需要优化(-O0),那么对matmul的调用就会在大约90毫秒内执行。如果使用任何优化(标志为-O1-O2-O3),则执行时间将增加到250毫秒左右。我尝试为inVectmatrix使用各种不同的大小,但在所有情况下,-O0选项的性能都比其他三个优化标志至少高出2.5倍。如果我使用只有几百个元素的较小的矩阵,但是循环多次调用来匹配,那么性能的影响就更糟了,接近10倍。

有什么办法可以避免这种行为吗?我需要在代码的某些部分使用优化,但同时,我也希望尽可能高效地执行矩阵乘法。

我用命令sandbox.f90编译包含下面代码的文件gfortran -ON sandbox.f90,其中N是一个优化级别0-3 (没有使用其他编译器标志)。outVect的第一个值被打印出来仅仅是为了防止gfortran优化变得聪明,并且完全跳过对matmul的调用。

我是Fortran新手,所以如果我错过了一些显而易见的事情,我会提前道歉。

代码语言:javascript
运行
复制
program main
implicit none
    real :: inVect(20000), matrix(20000,10000), outVect(10000)
    real :: start, finish

    call random_number(inVect)
    call random_number(matrix)
        
    call cpu_time(start)
    outVect = matmul(inVect, matrix)
    call cpu_time(finish)

    print '("Time = ",f10.7," seconds. – First Value = ",f10.4)',finish-start,outVect(1)
end program main
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-18 13:13:48

首先,考虑到我可能错了。我第一次看到这个问题,我和你一样惊讶。

我刚刚研究了这个问题,我理解如下。优化-O0O3Ofast和.是为大多数一般(频繁)情况而写的。但是,在某些情况下(当-O3-O*<-O3效率低时),优化会导致一个缺点。这是因为这些优化调用导致特定任务执行时间更短的隐式标志。对于您的情况,-O3规定,除其他外,所有matmul()函数都将内联。这样的事情通常是好的,但是对于这个函数的大数组或多个调用来说不是必要的。不知何故,内联matmul()的成本比内联函数获得的增益更重要(至少我是这样认为的)。

为了避免这种行为,我建议使用标志-O3 -finline-matmul-limit=0来取消matmul函数的内联。使用标志-O3 -finline-matmul-limit=0会导致执行时间不超过为-O0获得的时间。

您可以使用-finline-matmul-limit=n,只有当所涉及的数组小于n时,才能内联matmul函数。为了简单起见,我使用n=0

我希望这对你有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66682180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档