为什么 Julia 编译器不优化这个循环?
Why doesn't the Julia compiler optimise this loop?
我对编译知之甚少,但我很惊讶地发现 Julia 编译器没有优化多个进程。
让我们考虑一下 Julia(这是一个 即时 编译器),让我们考虑一下这两个基本上做同样事情的代码。
n=1
@time for i = 1:10^8 n=n+1 end
elapsed time: 3.535394087 seconds (0 bytes allocated)
n=1
@time n=n+10^8
elapsed time: 6.599e-6 seconds (112 bytes allocated)
为什么现代编译器无法理解这个长循环只会将 10^8
添加到 n
?
下面这个例子我觉得更震撼
n=1
@time for i = 1:10^9 n=n end
elapsed time: 3.496573198 seconds (0 bytes allocated)
这是在全局范围内执行时的一个问题,并且与在类型可能发生变化的条件下进行优化有关,但在适当的情况下,情况会发生变化。将计算限制在一个函数内允许编译器做更多的事情。考虑同样的事情,但在函数中。
function f(n::Int64)
x = 0;
for i = 1:n
x = x + 1;
end
return x;
end
julia> @time f(100)
elapsed time: 2.93e-6 seconds (80 bytes allocated)
100
julia> @time f(Int64(1e11))
elapsed time: 4.632e-6 seconds (112 bytes allocated)
100000000000
通过使用code_native检查编译器输出,您可以看到循环已优化
julia> code_native(f,(Int64,))
Source line: 6
push RBP
mov RBP, RSP
test RDI, RDI
jg L15
xor EDI, EDI
Source line: 6
L15: mov RAX, RDI
pop RBP
ret
我对编译知之甚少,但我很惊讶地发现 Julia 编译器没有优化多个进程。
让我们考虑一下 Julia(这是一个 即时 编译器),让我们考虑一下这两个基本上做同样事情的代码。
n=1
@time for i = 1:10^8 n=n+1 end
elapsed time: 3.535394087 seconds (0 bytes allocated)
n=1
@time n=n+10^8
elapsed time: 6.599e-6 seconds (112 bytes allocated)
为什么现代编译器无法理解这个长循环只会将 10^8
添加到 n
?
下面这个例子我觉得更震撼
n=1
@time for i = 1:10^9 n=n end
elapsed time: 3.496573198 seconds (0 bytes allocated)
这是在全局范围内执行时的一个问题,并且与在类型可能发生变化的条件下进行优化有关,但在适当的情况下,情况会发生变化。将计算限制在一个函数内允许编译器做更多的事情。考虑同样的事情,但在函数中。
function f(n::Int64)
x = 0;
for i = 1:n
x = x + 1;
end
return x;
end
julia> @time f(100)
elapsed time: 2.93e-6 seconds (80 bytes allocated)
100
julia> @time f(Int64(1e11))
elapsed time: 4.632e-6 seconds (112 bytes allocated)
100000000000
通过使用code_native检查编译器输出,您可以看到循环已优化
julia> code_native(f,(Int64,))
Source line: 6
push RBP
mov RBP, RSP
test RDI, RDI
jg L15
xor EDI, EDI
Source line: 6
L15: mov RAX, RDI
pop RBP
ret