[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: [ANN] Ravi (a Lua 5.3 dialect) with LLVM JIT Compilation technology - Alpha Release 0.12
- From: Dibyendu Majumdar <mobile@...>
- Date: Wed, 9 Dec 2015 00:38:41 +0000
On 8 December 2015 at 02:41, Simon Cozens <email@example.com> wrote:
> Hello! I just tried running SILE under Ravi.
> There were a couple of problems setting it up:
> Luarocks worked fine but it installed code into "/usr/local/lib/lua/
> 5.3" and "/usr/local/share/lua/ 5.3" (note the space).
> Using "Ravi" as the LUA_VERSION name in lua.h is perfectly correct but
> it breaks the AX_LUA_HEADERS autoconfig macro.
> Otherwise, everything works, and all tests pass!
Thanks very much for trying out Ravi and for reporting above issues. I
have not yet tried using Luarocks but I will have a look at the issues
and try to resolve them.
> However, I am having problems with the JIT. Ravi typeset the SILE manual
> in 13 seconds without JIT. Auto mode fails spectacularly - SILE takes up
> huge amounts of RAM and there's no output. Turning on the JIT for
> hot-spot functions doesn't seem to make a lot of difference; if anything
> it makes it slower.
Does SILE create a lot of Lua functions dynamically?
I'd be interested to know what auto options you tried out.
> My guess is that the JIT makes sense for individual functions which run
> for a long time, but for a collection of small functions which call each
> other it doesn't seem to buy you very much at all. Maybe when you can
> insert the code from one function into another we might see some speedup.
JIT compiling existing Lua code does not give that much improvement as
the JIT optimisations are largely ineffective in the presence of the
typing checking that occurs in typical Lua code. For example see my
benchmarks at https://github.com/dibyendumajumdar/ravi/blob/master/readthedocs/ravi-benchmarks.rst.
So for best results the compiler needs to be helped by annotating
Additionally there are following issues:
LLVM compiler is slow so the cost of compiling is high and only worth
if the Lua function will be used again and again. So the JIT compiler
is more useful in a server application that is likely to run the same
functions many many times.
The JIT compilation occurs in the same OS thread as the execution so
that means that while JIT compilation is occuring the execution is
blocked. An obvious optmization is to do the compilation in a separate
Each Lua function goes into its own module (compilation unit) in LLVM
at present - this makes each function autonomous and therefore garbage
collectible - but this is not optimum usage of memory. I need to work
on putting multiple functions in a module; but this would mean that
the module cannot be collected until all functions in it are
collected. I am also holding on to the LLVM artifacts associated with
the module - such as Execution Engine - I haven't yet implemented a
solution for freeing up unnecessary LLVM objects after compilation
The memory usage grows also due to the fact that the garbage collector
is unaware of the JIT code being attached to Lua functions; to work
around this after every 200 compilations I force a full GC which slows
things down (https://github.com/dibyendumajumdar/ravi/issues/50). This
is a configurable parameter (ravi.gcstep(N)) that can be changed but
the downside of removing it altogether (i.e. set to 0) is that the GC
does not clean up memory fast enough. I need to find a better way to
keep the GC going fast enough.