julia - 使用 `@code_lowered` 是解决 Julia 中的性能问题的有效方法吗?

标签 julia

我想看看我写的 Julia 代码是否有任何性能问题。我知道 @code_lowered可以很好地了解编译器是如何解释代码的,但是这 @code_lowered 究竟是什么时候?是最有用的。是否有某些性能或其他问题可以很好地突出显示(如果您能理解打印输出),而在其他情况下它不太有用?

我也知道 Julia 中还有其他很棒的分析工具,我只是想大致了解每个工具的用例。

julia> @code_lowered Int(1.0)
CodeInfo(
1 ─ %1  = -9.223372036854776e18 <= x
└──       goto #3 if not %1
2 ─       @_3 = x < 9.223372036854776e18
└──       goto #4
3 ─       @_3 = false
4 ┄       goto #6 if not @_3
5 ─ %7  = Base.round(x, Base.RoundToZero)
│         @_4 = %7 == x
└──       goto #7
6 ─       @_4 = false
7 ┄       goto #9 if not @_4
8 ─ %12 = Base.unsafe_trunc(Int64, x)
└──       return %12
9 ─ %14 = Base.InexactError(:Int64, Int64, x)
│   %15 = Base.throw(%14)
└──       return %15
)

最佳答案

@code_lowered 对理解性能没有用处。@code_warntype 是最好的。

基本上不同的步骤:

解析:

源代码 -> 抽象语法树(就像用宏操作的那样),循环和条件等 block 是树中的分支。
您可以通过引用源代码来查看它。

quote
    if x>1
       x=x-1
    end
end

降低:

抽象语法树->降低中间表示(IR),我认为最好将其描述为抽象语法列表,

基本上没有做任何事情,没有优化等。
只是树形已经变成了一个列表,其中没有任何子表达式,每个临时都在自己的行上。循环和 ifs 变成了各种跳转(如标签和条件 goto)

一些事情会改变为降低的表示形式,例如 end 中的 xs[end-1] 变为 lastindex(xs)
这种降低可以完全提前完成,它不需要 JIT。
它只是语法的转换

您可以通过 @code_lowered f(x) 访问它以获取某些函数 f 带参数 x
或者如果你有 Method 那么你可以做 Base.uncompressed_ast(method)

特化

类型信息被使用,优化器运行。
事物被内联,总是为真或假的条件被删除(例如检查类型)。
降低的 IR 变成了 Typed IR。
  • @code_typed f(x) 为您提供此信息。
  • @code_typed optimize=false f(x) 在不运行优化步骤的情况下为您提供此信息。
  • @code_warntype f(x) 通过突出显示类型不稳定性的额外有用的性能注释为您提供此功能

  • 这是最有用的层之一。
    可能仅次于源代码本身。

    代码生成 (LLVM)

    这就是我们 Typed IR 变成 LLVM 的地方。
    LLVM 在内部就像一堆中间表示一样。
    LLVM 自己进行了大量优化。
    例如各种数学内在常数在这个阶段传播。

    通过 @code_llvm f(x) 访问它

    这是 Typed 之后的下一个最有用的阶段。
    (与 native 机器代码绑定(bind),取决于您对 LLVM IR 的阅读是否比汇编更好或更差)。

    代码生成(程序集)

    LLVM 变成了汇编,
    基本上是人类可读的机器代码。
    通过 @code_native f(x) 访问它

    之后只有假设,机器码。
    虽然我怀疑程序集通常会被绕过,因为它们是 1-1,因为它们从 LLVM 直接转到机器代码。

    另见:https://stackoverflow.com/a/43456211/179081

    关于julia - 使用 `@code_lowered` 是解决 Julia 中的性能问题的有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58137665/

    相关文章:

    tuples - 使用函数在 Julia 中重复值

    c++ - julia Cxx 在模块中封装不同的行为

    julia - 映射,在 Julia 中用 `|>` 减少

    julia:如何读取 bz2 压缩文本文件

    linux - 当我创建一个临时文件/目录时,它何时会被删除?

    julia - 复制元组并修改

    julia - 如何使用 ModelingToolkit.jl 动态创建变量

    Julia 多次调度与子类型不匹配

    julia - 为什么对 Julia 矩阵向量乘法强制执行顺序加快了?

    julia - 如何在 Julia 中分析代码?