虚拟机之比较,lua 5 的实现
前段把自己的虚拟机和编译器完成后,曾经和lua5 做过一个比较。比较的结果很沮丧,我的虚拟机只能达到 lua 5 一半多点的速度。所以很不服气的又读了一段 lua5 的源码。而之前我是一段一段的看 lua source code 的,甚至 lua 4 和 lua5 的是在不同时期去读的,当然我也知道其间巨大的不同。其实,对于简单程序来说,我的虚拟机是有速度优势的,而且比
前段把自己的虚拟机和编译器完成后,曾经和 lua5 做过一个比较。比较的结果很沮丧,我的虚拟机只能达到 lua 5 一半多点的速度。所以很不服气的又读了一段 lua5 的源码。而之前我是一段一段的看 lua source code 的,甚至 lua 4 和 lua5 的是在不同时期去读的,当然我也知道其间巨大的不同。
其实,对于简单程序来说,我的虚拟机是有速度优势的,而且比 lua 快很多,我把它归咎于 coding 的技巧。但是在设计方向上却败下阵来。因为 lua 5 早已经是基于寄存器的虚拟机了,而我还在用基于堆栈的虚拟机。虽然我对其做了改良,向基于寄存器方向做了靠拢,但是还是不如纯粹的寄存器虚拟机。
最近几天仔细考虑了基于寄存器的虚拟机的实现难度,虽然自己也可以继续干,但是目前项目很紧,决定先缓一阵子,多来点思考沉淀吧。
今天休假,读了一些信箱里订阅的 lua maillist ,想看看 lua 5.1 到底做了些啥改动。由于最近自己做了好些类似的工作,更容易对 lua 的进展去理解了。最后发现,lua 的改进集中在 GC 上面。这点很合我意,其实我自己实现的东西,最得意的莫过于 gc,绝对是优于 lua 的。lua 现在在做分代 gc ,我在考虑并行的方案。大约都是为了解决 gc 的一些个头痛的东西。不过 lua 的 gc 终究不是内存整理的,在受限内存环境下,表现相对不是特别好。另外,lua 为了最求速度等,在深层次递归的支持上也有些问题,会导致堆栈满。我曾经写过一个用递归算数列和的程序,递归层次过深,lua 就处理不了了,我的虚拟机是可以胜任的。当然这对一般的应用都不是问题。
毕竟 lua 发展了 10 多年,可以借鉴的东西实在太多了。我那区区三周的玩具就当是练手的开始吧。今天仔细读了一遍 <a href="http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/sblp2005.pdf">the implementation of Lua 5.0</a> ,如果有人对脚本语言实现有同样的兴趣,推荐阅读。
从这个 paper 中我们可以了解几件事情,虽然通过读源码也可以了解(我就是先通过阅读源码的)但是读这个可以更休闲一些。
lua5 已经是完全 Register-based virtual machine ,可以说是世界上第一个被广泛应用的register-based 脚本虚拟机了。这点,现在的 Java JVM 还有 .NET 都还是 Stack-based 。据说 perl6 打算做成 Register-based 了 :) 当然我的语言也有此计划 ,呵呵。Registere-based 虚拟机相对难写,看来是个挑战。
lua5 优化了 table 的实现,这点我前面的 blog 里提到过,这篇 paper 也做了详细阐述。
lua5 增加了 coroutine 的实现,这点我考虑过,自从我把自己的虚拟机改成系统堆栈无关后,做多几个 thread 无非创建多一个堆栈而已,不难实现。 lua5 的 coroutine 也是每个 thread 有独立堆栈的。(实际上有两个堆栈)
lua 也是一个one-pass 的基于递归下降算法的 compiler ,paper 中提到,one-pass 的 compiler 是 hard-written 的,这点我是深有体会啊。写 compiler 那几天,脑子里翁翁乱叫,写了两整天不敢向仓库提交一行代码。不过写出来的好处是显而易见的,就和 paper 里说的一样,smaller, more efficient, more portable, and fully reentrant :)
前几天在想,一个弱类型的语言,Object 的描述信息能不能比 lua 这种更小。lua 用了一个独立的字描述类型,然后用 union 来存放不同类型的数据,这个也是我用的方法。前几天想了个办法,那就是一般指针由于对齐的原因,末两位永远都是 0 。(如果我们以 8 对齐的话,末三位都是 0)这样就有点额外的信息来保存数据类型了,整数可以用 30 或 31bit 来表示都是够的。
今天读这篇 paper 发现前人已经用过了,比如 Smalltalk80 ,不过 paper 解释了 lua 不这样做的原因。当然,我自己的语言倒是可以一试的 :)
至于 lua5 用的指令集,每个 instruction 只用 4 个字节,其实现方法还是很巧妙的,这个前几天读源码的时候已经领教过了。当时我想找到我的语言的速度究竟慢在哪里,才发现是循环中, i=i+1 这样的操作。基于寄存器的虚拟机自然可以运行的更快了。而且我的虚拟机的 instruction 是 8 字节的,而 lua 却只用 4 字节,数据短了,效率也能提高。
读完这篇 paper 感觉很多地方 lua 都是鄙视 python 的低效 :) 这点跟我在 GDC2004 上参加的 lua round table 的感觉一样,一下就可以发展成 lua 和python 的"派系斗争" :) 我想 GDC2006 上 lua 派会更理直气壮一些,毕竟两年前用 lua4 的人远不如 lua5 的人,(我发言的时候特地让用 lua5 的人举了次手 :) 这次随着 lua 5.1 的 release ,lua在游戏行业中的地位将不可动摇了。
转载:http://blog.codingnow.com/2005/12/compare_with_lua_5.html
更多推荐
所有评论(0)