为啥 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 R Golang Python Swift Groovy C ++ C ++ Rust Scala Kotlin Ruby Fortran Julia C