Compiler construction 为什么';Julia编译器没有优化这个循环吗?

Compiler construction 为什么';Julia编译器没有优化这个循环吗?,compiler-construction,compilation,julia,Compiler Construction,Compilation,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) 为什么现代编译器不能理解

我对编译知之甚少,但我惊讶地发现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

这完全取决于编译器的开发人员在优化器上投入了多少精力。实际上,其他语言中的一些编译器确实执行了这种优化。我期望在如何编译代码方面有一些基本的限制。我认为你可以从你的评论中做出一个答案(最终添加一点解释,说明为什么构建能够执行此优化的编译器是一项艰巨的工作),这只是一个简单例子中的一个毫无根据的概括-1我理解为什么有人告诉我,将代码行封装到Julia中的函数中是一种很好的做法。非常感谢您对“在函数中约束求值允许编译器做更多事情”的回答+1评论。好的,但为什么?例如,如果
n
是一个全局对象,那么其他进程或线程或其他任何可能正在查看它并监视其增长的对象。它也可以表示一块硬件。我对Julia一无所知,但在其他一些环境中,您可以在地址空间中的特定点声明变量,从而将其映射到某个物理设备上。然后,写入序列不能“优化”,因为这可能会改变系统的设计行为。