为啥 Julia 代码性能比 Fortran 低很多?

Posted

技术标签:

【中文标题】为啥 Julia 代码性能比 Fortran 低很多?【英文标题】:why Julia code performance is much lower than Fortran one?为什么 Julia 代码性能比 Fortran 低很多? 【发布时间】:2021-08-07 10:14:57 【问题描述】:

我在几个地方读到 Julia 代码的性能(在某些条件下)可以与 Fortran 的性能进行比较。我在 Julia 中编写了以下代码:

Pi = 3.141592653589793238462643
n = 100000 
function integration_2d(n,Pi,sum)
       h = Pi/n
       for i=1:n
           x = h*(i-0.5)
           for j=1:n
               y = h*(j-0.5)
               sum = sum + cos(x + y)
           end
       end
       sum*h*h
end

平均执行时间为 180 秒。与使用-O3 选项编译的Fortran 代码相比,结构非常接近的Fortran 代码的执行时间为0.013 秒。我想知道 Julia 代码在哪里失去性能,任何评论都值得赞赏。谢谢。

【问题讨论】:

对于这样的声明,最好知道 1) 用于比较的 Fortran 版本,以及 2) 您如何对此进行基准测试的代码。 您正在计算cos 的总数为 100000^2 = 10^10 次。您声称在 Fortran 中这需要 0.013 秒。这意味着每个余弦评估需要 1.3*10^(-12) 秒。 CPU 可以在每纳秒 10^(-9) 秒内执行非常近似的一次操作。很明显,Fortran 代码并没有完成您认为它在运行时所做的工作。对于基准测试来说,这是一个持续存在的危险。你必须确保你测量的是你认为你正在测量的东西。 顺便说一句,不需要手动定义Pi,因为pi已经是Julia的内置常量了。 Fortran 编译器是否有可能使用 O3 优化重新排列代码,天真地编写为 O(N^2),类似于 @Vitality 发布的 O(N) 代码?如果是这样,Julia 是否可以实现同样的优化? 嗨,这是我在 Fortran 代码中犯的一个错误。我收集了部分金额,但没有打印出结果。因此,编译器忽略了整个计算。 【参考方案1】:

由于您没有提供 Fortran 代码,我假设您的代码使用 Fortran 实现的方式不同。您的 O(N^2) 算法需要 CPU 每秒 > ~10^12 次操作(即使使用汇编程序),我猜您没有使用超级计算机进行此测试:)。 我们可以以需要 O(N) 性能的方式实现您的算法。 Julia 代码如下所示:

function integration_2d(n, sum=0.0)
    h = π / n
    multiplier = 1
    for i = 2:2n
        z = h * (i - 0.5)
        sum = sum + multiplier * cos(z)
        if i <= n
            multiplier += 1
        else
            multiplier -= 1
        end
    end
    sum * h * h
end

julia> @time integration_2d(100000)
  0.002846 seconds

在我的笔记本电脑上,Wich 是 0.002846 秒(> 是您使用的 Fortran 时间的 4 倍)(因为您没有提供 Fortran 代码,所以我无法正确比较同一台机器上的性能)

【讨论】:

以上是关于为啥 Julia 代码性能比 Fortran 低很多?的主要内容,如果未能解决你的问题,请参考以下文章

Matlab 与 Julia 与 Fortran 中的速度

install julia with python

install julia with python

实时时间序列数据中的峰值信号检测Matlab R Golang Python Swift Groovy C ++ C ++ Rust Scala Kotlin Ruby Fortran Julia C

为啥性能测试显示我的代码列表比数组快得多? [复制]

与 Python+Numba LLVM/JIT 编译的代码相比,Julia 的性能