`
mryufeng
  • 浏览: 982726 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

LuaJIT 2 beta 3 is out: Support both x32 & x64(为什么会如此快?)

    博客分类:
  • Lua
阅读更多
LuaJIT's interpreter is fast, because:

•It's written in assembler.
•It keeps all important state in registers. No C compiler manages to do that on x86.
•It uses indirect threading (aka labeled goto in C).
•It has a very small I-cache footprint (the core of the interpreter fits in 6K).
•The parser generates a register-based bytecode.
•The bytecode is really a word-code (32 bit/ins) and designed for fast decoding.
•Bytecode decode and dispatch is heavily optimized for superscalar CPUs.
•The bytecode is type-specialized and patched on-the-fly.
•The dispatch table is patched to allow for debug hooks and trace recording. No need to check for these cases in the fast paths.
•It uses NaN tagging for object references. This allows unboxed FP numbers with a minimal cache footprint for stacks/arrays. FP stores are auto-tagging.
•It inlines all fast paths.
•It uses special calling conventions for built-ins (fast functions).
•Tons more tuning in the VM ... and the JIT compiler has it's own bag of tricks.
E.g. x=x+1 is turned into the ADDVN instruction. This means it's specialized for the 2nd operand to be a constant. Here's the x86 code (+ SSE2 enabled) for this instruction:

// Prologue for type ABC instructions (others have a zero prologue).
movzx  ebp, ah                  Decode RC (split of RD)
movzx  eax, al                  Decode RB (split of RD)

// The instruction itself.
cmp    [edx+ebp*8+0x4], -13     Type check of [RB]
ja     ->lj_vmeta_arith_vn
movsd  xmm0, [edx+ebp*8]        Load of [RB]
addsd  xmm0, [edi+eax*8]        Add to [RC]
movsd  [edx+ecx*8], xmm0        Store in [RA]

// Standard epilogue: decode + dispatch the next instruction.
mov    eax, [esi]               Load next bytecode
movzx  ecx, ah                  Decode RA
movzx  ebp, al                  Decode opcode
add    esi, 0x4                 Increment PC
shr    eax, 0x10                Decode RD
jmp    [ebx+ebp*4]              Dispatch to next instruction
Yes, that's all of it. I don't think you can do this with less instructions. This code reaches up to 2.5 ipc on a Core2 and takes 5-6 cycles (2 nanoseconds on a 3 GHz machine).
5
4
分享到:
评论
17 楼 linkerlin 2010-04-15  
Lua的软肋还是在GC上。
我上次和LuaJIT的开发者聊,他说,目前的Lua C API导致无法更新GC.
指针被暴露啊。GC没法改进成 拷贝分代GC.
16 楼 mryufeng 2010-03-09  
RednaxelaFX 写道
mryufeng 写道
你说的是翻译源码还是opcode?

翻译opcode,将opcode翻译为machine instruction。

解释与翻译的界限有点模糊。
如果以是否进行native code generation来界定是编译还是解释,那么编译是做native code generation的,而解释不做。
如果以是否直接利用硬件支持来进行instruction dispatch来界定,那么编译后生成的代码是直接靠硬件来做instruction dispatch,而解释器是用自己写的代码来做。
但这些都不是特别的精确,到底界限在哪里我也没有见到过什么好的定义。总之从程度上说,趋近于解释执行的方式在得到运行结果前对程序预先做的分析和处理较少,而趋近于编译的方式正好相反,在得到运行结果前对程序做了较多的分析和处理。

这帖里的代码可以看到很明显的用于instruction dispatch的代码:
jmp  [ebx+ebp*4]    Dispatch to next instruction

而如果是通过硬件支持直接做instruction dispatch的话,dispatch本身就是隐含在每条机器指令中的。


这个肯定是这样的. 提升的地方就是原来lua vm的dispatch代码下岗了, 等价的native code上岗了.

jit的用处就是产生更好的等价代码...
15 楼 RednaxelaFX 2010-03-09  
mryufeng 写道
你说的是翻译源码还是opcode?

翻译opcode,将opcode翻译为machine instruction。

解释与翻译的界限有点模糊。
如果以是否进行native code generation来界定是编译还是解释,那么编译是做native code generation的,而解释不做。
如果以是否直接利用硬件支持来进行instruction dispatch来界定,那么编译后生成的代码是直接靠硬件来做instruction dispatch,而解释器是用自己写的代码来做。
但这些都不是特别的精确,到底界限在哪里我也没有见到过什么好的定义。总之从程度上说,趋近于解释执行的方式在得到运行结果前对程序预先做的分析和处理较少,而趋近于编译的方式正好相反,在得到运行结果前对程序做了较多的分析和处理。

这帖里的代码可以看到很明显的用于instruction dispatch的代码:
jmp  [ebx+ebp*4]    Dispatch to next instruction

而如果是通过硬件支持直接做instruction dispatch的话,dispatch本身就是隐含在每条机器指令中的。
14 楼 mryufeng 2010-03-09  
RednaxelaFX 写道
mryufeng 写道
wkoffee 写道
好像通篇都是intepreter,没有jit什么事

jit做什么的 不就是把lua opcode intepret成x86码吗 那你以为jit做什么的?

同样是翻译语言,有口译和书面译的区别;同样是执行程序,也有解释(interpret)与编译(compile)的区别。《虚拟机 系统与进程的通用平台》一书中指出一类加速虚拟机执行程序的方式就是“动态翻译”(dynamic translation),而在高级语言虚拟机中这一般就被叫做编译。
这帖中引用的资料确实只是讲了LuaJIT中的解释器部分。LuaJIT是混合执行模式的虚拟机,同时具有解释器与JIT编译器的部分。


你说的是翻译源码还是opcode?
13 楼 wkoffee 2010-03-09  
mryufeng 写道
wkoffee 写道
好像通篇都是intepreter,没有jit什么事

jit做什么的 不就是把lua opcode intepret成x86码吗 那你以为jit做什么的?

这个就是个用汇编写的解释器,用c写就是一个大的switch case,用汇编写就是一个dispatch table。
12 楼 RednaxelaFX 2010-03-09  
mryufeng 写道
wkoffee 写道
好像通篇都是intepreter,没有jit什么事

jit做什么的 不就是把lua opcode intepret成x86码吗 那你以为jit做什么的?

同样是翻译语言,有口译和书面译的区别;同样是执行程序,也有解释(interpret)与编译(compile)的区别。《虚拟机 系统与进程的通用平台》一书中指出一类加速虚拟机执行程序的方式就是“动态翻译”(dynamic translation),而在高级语言虚拟机中这一般就被叫做编译。
这帖中引用的资料确实只是讲了LuaJIT中的解释器部分。LuaJIT是混合执行模式的虚拟机,同时具有解释器与JIT编译器的部分。
11 楼 mryufeng 2010-03-09  
wkoffee 写道
好像通篇都是intepreter,没有jit什么事

jit做什么的 不就是把lua opcode intepret成x86码吗 那你以为jit做什么的?
10 楼 wkoffee 2010-03-09  
好像通篇都是intepreter,没有jit什么事
9 楼 mryufeng 2010-03-08  
多谢指教 跟你学了很多东西! 俺是你的粉丝哦...
8 楼 RednaxelaFX 2010-03-08  
mryufeng 写道
我记得1.x就有呀 根据代码的hot度 来加速的 不知道是不是叫 trace compiler, 时间长了 记得不太清楚了...

adaptive compilation跟trace compilation不是同一种概念。根据代码热的程度做不同程度优化的是adaptive compilation;以trace为单元(相对于其它编译单元,例如函数/方法为单元)来编译的是trace compilation ^_^
7 楼 mryufeng 2010-03-08  
RednaxelaFX 写道
mryufeng 写道
lua 1.x的时候就只有trace compiler技术是个亮点.印象最深的是dynasm. 2.0的变化太大了 一下子就爆发出来了...

LuaJIT 1.x貌似没有用trace compiler,JIT编译的方式就是很常见的以函数为单位的。在2.0才开始转用trace compiler。用了trace compiler最有名的大概是TraceMonkey了吧,很多人都应该听说过这个;Android的Dalvik里的JIT也有用;其它一些研究性质的VM也有用,不过还不是很普及。


我记得1.x就有呀 根据代码的hot度 来加速的 不知道是不是叫 trace compiler, 时间长了 记得不太清楚了...
6 楼 RednaxelaFX 2010-03-08  
mryufeng 写道
lua 1.x的时候就只有trace compiler技术是个亮点.印象最深的是dynasm. 2.0的变化太大了 一下子就爆发出来了...

LuaJIT 1.x貌似没有用trace compiler,JIT编译的方式就是很常见的以函数为单位的。在2.0才开始转用trace compiler。用了trace compiler最有名的大概是TraceMonkey了吧,很多人都应该听说过这个;Android的Dalvik里的JIT也有用;其它一些研究性质的VM也有用,不过还不是很普及。
5 楼 mryufeng 2010-03-08  
lua 1.x的时候就只有trace compiler技术是个亮点.印象最深的是dynasm. 2.0的变化太大了 一下子就爆发出来了...
4 楼 RednaxelaFX 2010-03-08  
啊,上面码字的时候被打了个岔写漏了……我是想说标记为红色的是Strongtalk与HotSpot也有的特性,而绿色的是Strongtalk中存在但HotSpot中没有的特性——因为Java(早期被认为)不需要tagged pointer
3 楼 RednaxelaFX 2010-03-08  
mryufeng 写道
LuaJIT's interpreter is fast, because:

It's written in assembler.
It keeps all important state in registers. No C compiler manages to do that on x86.
It uses indirect threading (aka labeled goto in C).
It has a very small I-cache footprint (the core of the interpreter fits in 6K).
•The parser generates a register-based bytecode.
•The bytecode is really a word-code (32 bit/ins) and designed for fast decoding.
•Bytecode decode and dispatch is heavily optimized for superscalar CPUs.
•The bytecode is type-specialized and patched on-the-fly.
The dispatch table is patched to allow for debug hooks and trace recording. No need to check for these cases in the fast paths.
It uses NaN tagging for object references. This allows unboxed FP numbers with a minimal cache footprint for stacks/arrays. FP stores are auto-tagging.
•It inlines all fast paths.
It uses special calling conventions for built-ins (fast functions).
•Tons more tuning in the VM ... and the JIT compiler has it's own bag of tricks.

标为红色的那些在Strongtalk里也是如此。
Strongtalk中有自己实现的汇编器,其解释器是通过代码控制汇编器在启动VM时生成出来的,也可以认为是“用汇编写的”。
它也是用indirect-threading(或者说token-threading),跟LuaJIT 2不同的是它的指令的操作码是字节码(只占8位)。
Strongtalks的字节码是基于栈的指令集,但通过“栈顶缓存”优化(top-of-stack caching)它比基于寄存器版本的同类实现只慢一点(而占用的内存空间小一些)。
Strongtalk也用tagged pointer来直接在指针里存放小整数等对象的值,减少了GC的压力。
Strongtalk也对直接调用VM内部函数有优化。

而Strongtalk是1994年到1996年在做的,后来则演化进了HotSpot里,将一些Java用不到的动态特性去除了,解释器稍微简化了些并且更快了。这些都并不是特别新的技术了,不过除了几家大厂的JVM外,其它VM就在近两三年才开始慢慢跟上时代的步伐……
看看HotSpot的解释器的一张截图:http://rednaxelafx.iteye.com/picture/52954
也是非常简洁的……

LuaJIT比较新的部分是它的trace compiler。这种技术现在只在很少的VM中得到了应用。

另外:打个广告,之前在JavaEye开了个高级语言虚拟机的圈子,欢迎来讨论相关话题。这帖就很合适,哈哈~
2 楼 dennis_zane 2010-03-08  
高科技,太牛了
1 楼 mryufeng 2010-03-08  
真牛B的技术!!!

相关推荐

    LuaJIT-2.1.0-beta3

    在LuaJIT 2.1.0-beta3中,我们可能会发现以下关键特性: 1. **兼容性**:此版本与Lua 5.1兼容,但同时引入了一些Lua 5.2的语法特性,如新的操作符和函数。这意味着你可以使用大部分5.2版本的新功能,而无需完全迁移...

    LuaJIT-2.1.0-beta3 已编译好的版本win10下编译LuaJIT-2.1.0-beta3-win10-by-ze

    LuaJIT-2.1.0-beta3 已编译好的版本win10下编译 luajit.exe lua51.dll lua51.lib luajit.lib LuaJIT-2.1.0-beta3_win10_by_zengfr.zip

    luajit2.1 beta2 编译代码

    luajit2.1beta cocos2dx 编译代码 32 64 cd windows/32 luajit.exe -b test.lua test32.luac cd windows/64 luajit.exe -b test.lua test64.luac

    LuaJIT-2.1.0-beta3.tar.gz

    在本文中,我们将深入探讨 LuaJIT 的核心特性、如何与 pgdb 集成,以及如何安装和使用 LuaJIT-2.1.0-beta3 版本。 首先,LuaJIT 是 Lua 解释器的优化版本,它不仅包含了一个解释器,还包含了即时编译器(JIT),...

    LuaJIT-2.1.0-beta2

    3. **增强的元表和操作符**:LuaJIT 2.1.0-beta2扩展了元表的功能,允许用户自定义操作符行为,从而实现更灵活的编程模式。 4. **内存管理优化**:LuaJIT的内存管理系统进行了优化,减少了内存分配和释放的开销,...

    cocos LuaJIT 2.1.0-beta3 android, ios支持

    cocos LuaJIT 2.1.0-beta3 android, ios支持 cocos3.17中luajit默认是LuaJIT 2.1.0-beta2, bug较多 升级到LuaJIT 2.1.0-beta3会用到 编译环境: ndk api level 21 支持ios 12.1

    LuaJIT 2.0.0-beta3 for Windows 可执行文件

    LuaJIT 2.0.0-beta3 是一个高度优化的 Lua 虚拟机实现,专为提高性能而设计。这个版本是针对 Windows 操作系统的,特别提到了它是32位版本,这意味着它适用于运行在32位 Windows 操作系统上的应用程序。LuaJIT 不仅...

    LuaJIT 2.0.0 beta8

    LuaJIT 2.0.0 beta8 是一个高度优化的 Lua 虚拟机实现,它基于 Just-In-Time (JIT) 编译技术,能够显著提升 Lua 代码的执行效率。这个版本是 0624 版本,意味着它在2006年4月24日发布。在LuaJIT中,JIT编译器会实时...

    Luajit 2023编译成品及源码 android arm64 ios 最新luajit 2.1.0 v2.1.ROLLING

    LuaJIT 是一款高效、开源的 Lua 解释器和 Just-In-Time (JIT) 编译器,由 Mike Pall 开发。它将 Lua 语言的性能提升到了接近原生代码的程度,广泛应用于游戏开发、服务器脚本、嵌入式系统等领域。在 Android 和 iOS ...

    luajit64 for cocos2d-x 2.2.6 above

    《LuaJIT64在Cocos2d-x 2.2.6及以上版本中的应用与FFI支持》 LuaJIT64是一款高效、优化的Lua虚拟机实现,专为64位架构设计,它在Cocos2d-x游戏引擎环境中扮演着至关重要的角色。Cocos2d-x是一款广泛使用的开源2D...

    luajit beta10 x86/64版二进制文件

    总的来说,这个压缩包提供了在Windows平台上运行LuaJIT Beta 10所需的基本组件,允许开发者和用户在他们的系统上直接执行优化过的Lua代码,享受更快的执行速度和更强大的功能。无论是进行性能测试、开发新的脚本应用...

    2.1.0-beta1_luajit_LuaJIT-2.1.0_

    LuaJIT是一个高效的Lua虚拟机实现,它以其优化的Just-In-Time(JIT)编译器而闻名。本文将深入探讨LuaJIT 2.1.0-beta1版本的特性和使用。 首先,"2.1.0-beta1"表明这是LuaJIT的一个测试版本,属于2.1版本系列的第一...

    cocos2d-x+luaJIT

    《cocos2d-x与LuaJIT的深度整合与应用》 在游戏开发领域,cocos2d-x是一个广泛使用的2D游戏引擎,它基于C++编写,支持多平台,包括iOS、Android以及桌面系统。而LuaJIT则是一款优化过的Lua虚拟机,它的执行效率极高...

    luajit_x64_gc64.zip

    总结来说,"luajit_x64_gc64.zip"是一个专为Windows x64平台优化的LuaJIT版本,包含了一个预编译的64位可执行文件和必要的库文件。通过使用VS2017进行编译并启用GC64模式,它能提供高性能的Lua脚本执行能力,特别是...

    Luajit 静态库(含32位和64位)

    LuaJIT 是一款高效的 Lua 虚拟机实现,它结合了 Just-In-Time (JIT) 编译器,能够将 Lua 代码编译为原生机器码,从而获得接近 C 语言的运行速度。本资源包含 Luajit 的静态库,支持32位和64位操作系统,这使得开发...

    luajit 2.1.0 bate解密工具

    luajit 2.1.0 bate解密工具,批量解密可使用bat脚本 for /r C:\Luas %%i in (*.lua) do @python C:\ljd-master2.1.0b2\main.py %%i > %%i.delua pause

    LuaJIT 2.0.3源码

    在IT行业中,尤其是在游戏开发领域,LuaJIT 被广泛应用于游戏核心逻辑,因为它的执行效率远超标准 Lua 解释器,能够为游戏运行提供更快的速度和更低的资源消耗。 首先,我们来深入了解一下 LuaJIT 的核心特点: 1....

    luajava-x32-x64.zip

    这个压缩包"luajava-x32-x64.zip"包含了luajava-1.1.jar的64位和32位版本,以及对应的luajava-1.1.dll文件,确保了不同系统环境下的兼容性。经过测试,这些文件已被验证为可用,对于需要在Java项目中使用Lua功能的...

    LuaJIT2-8(Lua解释器——C语言编写)

    LuaJIT2-8是Lua解释器的一个版本,它以其高效和快速的执行性能而闻名。LuaJIT是一个Just-In-Time (JIT)编译器,它将Lua脚本转换为机器码,从而显著提高了执行速度。这个版本是2.0.0-beta8,意味着它是该系列中的一个...

    cocos2d-x 支持arm64-v8a 的 luajit.a

    描述中的"LuaJIT 2.1.0-beta3"是一个高效的Lua虚拟机实现,它将Lua代码编译为机器码,显著提高了执行速度。LuaJIT在Cocos2d-x中常用于游戏脚本,因为它提供了轻量级、快速且易于集成的脚本解决方案。当游戏需要在...

Global site tag (gtag.js) - Google Analytics