gpt4 book ai didi

LuaJIT 2 优化指南

转载 作者:行者123 更新时间:2023-12-03 09:57:50 33 4
gpt4 key购买 nike

我正在寻找有关如何为 LuaJIT 2 优化 Lua 代码的好指南.它应该关注 LJ2 的细节,比如如何检测哪些跟踪正在被编译,哪些不是,等等。

任何指针?收集到 Lua ML 帖子的链接可以作为答案(在此处总结这些链接的加分点。)

更新:我已将标题文本从“分析”更改为“优化”指南,因为这更有意义。

最佳答案

更新

Mike 最近为 LuaJIT 创建并发布了一个很棒的轻量级分析器,你可以找到它 here .

更新

维基在这方面获得了更多的页面,特别是 this one ,其中详细介绍了原始答案中未提及的一些额外内容,并且基于 mailing list post通过迈克。

LuaJIT 最近推出了自己的 wikimailing list ,伴随着这些事情而来的是更多关于加速 LuaJIT 代码的 gem 。

现在 wiki 很薄(但一直在寻找人们添加它),但是,最近添加的一个很棒的页面是 a list of NYI functions . NYI 函数会导致 JIT 退出并回退到解释器,因此很明显应该尽可能避免在热路径上使用 NYI 函数,尤其是在循环中。

邮件列表中的一些感兴趣的主题:

  • FFI Array Performance
  • An interesting discussion on GC gotcha's
  • Some more small gotcha's

  • 并且只是重复下面所说的内容(因为它很有帮助), -jv是性能调优的最佳工具,也应该是你排查故障的第一站。

    原答案

    我怀疑您实际上会在这方面找到很多东西,主要是因为 LJ2 仍处于测试阶段,因此大多数配置文件都是天真地完成的,因为没有针对 LJ2 特定事物(例如跟踪记录器)的调试 Hook 。

    从好的方面来说,新的 FFI 模块确实允许直接调用高分辨率计时器(或分析 API,如 VTune/CodeAnalyst),您可以通过这种方式进行分析,但其他任何事情都需要扩展到 LJ2 JIT 核心,这应该不会太难,因为代码很清楚并且有注释。

    跟踪记录器命令行参数之一(取自 here ):

    The -jv and -jdump commands are extension modules written in Lua. They are mainly used for debugging the JIT compiler itself. For a description of their options and output format, please read the comment block at the start of their source. They can be found in the lib directory of the source distribution or installed under the jit directory. By default this is /usr/local/share/luajit-2.0.0-beta8/jit on POSIX systems.



    这意味着您可以使用命令中的模块代码来形成 LuaJIT 2 的分析模块的基础。

    更新

    随着问题的更新,这变得更容易回答了。所以让我们从源头开始, LuaJIT.org :

    在手动优化代码之前,检查 JIT 的优化调优资源总是一个好主意:

    编译

    来自 Running页面我们可以看到设置JIT参数的所有选项,为了优化,我们关注 -O选项。 Mike 立即告诉我们启用所有优化对性能的影响最小,因此请确保在 -O3 中运行。 (现在是默认设置),因此这里对我们来说真正有值(value)的唯一选项是 JIT 和 Trace 阈值。

    这些选项非常特定于您正在编写的代码,因此除了默认值之外没有通用的“最佳设置”,但不用说,如果您的代码有很多循环,请尝试循环展开并计算执行时间(但如果您正在寻找冷启动性能,则在每次运行之间刷新缓存)。
    -jv也有助于避免知道 issues/'fallbacks'这将导致 JIT 进行救助。

    除了 FFI tutorial 中的一些小花絮之外,该站点本身并没有提供太多关于如何编写更好或更优化的代码的信息。 :

    函数缓存

    函数缓存在 Lua 中是一个很好的性能助推器,但在 LuaJIT 中不太重要,因为 JIT 自己做了大部分优化,重要的是要注意 FFI C 函数的缓存是 ,最好缓存它们所在的命名空间。

    页面上的一个例子:

    坏的:
    local funca, funcb = ffi.C.funcb, ffi.C.funcb -- Not helpful!
    local function foo(x, n)
    for i=1,n do funcb(funca(x, i), 1) end
    end

    好的:
    local C = ffi.C          -- Instead use this!
    local function foo(x, n)
    for i=1,n do C.funcb(C.funca(x, i), 1) end
    end

    FFI 性能问题

    Status部分详细介绍了降低代码性能的各种构造和操作(主要是因为它们没有被编译,而是使用 VM 回退)。

    现在我们转到所有 LuaJIT gem 的来源, Lua mailing list :
  • Avoiding C Calls and NYI Lua calls in loops :如果您希望 LJ2 跟踪器启动并提供有用的反馈,则需要避免跟踪编译器无法执行的 NYI(尚未实现)函数或 C 调用。因此,如果您有任何可以导入 lua 并在循环中使用的小型 C 调用,请导入它们,在最坏的情况下,它们可能比 C 编译器实现“慢 6%”,充其量更快。
  • Use linear arrays over ipairs :根据 Mike 的说法,与其他方法相比,pairs/next 总是会更慢(还有一个关于跟踪器符号缓存的小花絮)。
  • Avoid nested loops :每个嵌套级别都需要额外的一次跟踪,并且优化程度会稍微降低,特别是避免具有较低迭代次数的内部循环。
  • You can use 0-base arrays :Mike 在这里说,与标准 Lua 不同,LuaJIT 对基于 0 的数组没有性能损失。
  • Declare locals in the most inner scope as possible : 没有真正的解释为什么,但是 IIRC 这与 SSA 活力分析有关。还包含一些关于如何避免过多本地人的有趣信息(这打破了活力分析)。
  • Avoid lots of tiny loops :这会扰乱展开的启发式方法,并会减慢代码速度。

  • 小花絮:
  • FFI Tips
  • 从 beta8 开始,我们有了字节码,可以通过删除解析步骤来提高冷启动性能。
  • Some general guidelines关于迈克的 FFI 类型
  • Reuse metatables尽可能多
  • 提速 Lua -> C -> Lua looping
  • LJ2 没有 Lua 的 metatable bugs并避免代理表,以便正确缓存。
  • 尽可能更新 Git HEAD,它总是包含修复和加速。

  • 分析工具可用于普通 Lua,但是,有一个较新的项目与 LuaJIT 正式兼容(不过我怀疑它是否会考虑任何 LuaJIT 功能), luatrace . Lua wiki 在 optimization tips 上也有一个页面对于普通的 Lua,这些需要在 LuaJIT 下测试其有效性(这些优化中的大部分可能已经在内部执行),但是,LuaJIT 仍然使用默认 GC,这使它成为手动优化 yield 仍然很大的一个领域(直到 Mike 添加了他在这里和那里提到的自定义 GC)。

    LuaJIT 的源代码包含一些用于摆弄 JIT 内部的设置,但是,这些需要大量测试才能针对特定代码进行调整,
    事实上,完全避免它们可能会更好,尤其是对于那些
    不熟悉 JIT 的内部结构。

    关于LuaJIT 2 优化指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7167566/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com