[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: LuaThreads with LuaJIT (and maybe lua_tcc)
- From: "Jerome Vuarand" <jerome.vuarand@...>
- Date: Tue, 11 Apr 2006 17:52:43 -0400
Thanks a lot for all that information, some ideas you talked about may help me progress.
I've considered LuaTasks and HelperThreads, but that do not fulfil my problem. The purpose of my threads are to implement a kind of multi agent system, and the objective is to impose absolutely no constraint to the agent writer (for several reasons, one of them being that the code writer may be another agent). Ultimately I want him to be able to write an infinite loop with some behaviour accessing some global shared memory. Concurrent access at the user language level (Lua) is to be managed by the user himself, I just want that underlying system (Lua implementation in C and OS API) to be stable and to keep its data structures from corruption.
The hardware where all that is supposed to run is not well defined yet, but it surely have multiple CPU cores (a core per agent/thread is not out of question) which access a shared memory space. So I have to manage some form of program execution parallelism while accessing concurrently to data.
To avoid C structure corruption locks are a must, whatever implementation I use. I used LuaThreads because the principle and the API are what I need (true and free parallelism while in the same world), though I know its locking mechanism is too basic and not meant to be used on multi-cpu architectures. Finer lock granularity is something that can be implemented while keeping the same API (and I think its a natural evolution path of LuaThreads). Multiple concurrent read access do not need locking. I think lua implementation has no C writing side effects on Lua reads (correct me if I'm wrong), so that should be feasible and reasonnably fast to implement a smart locking system at the object level (table, string, userdata) allowing concurent reads but only a single write at a given time.
And just a final word about core/lib distinction. Initially Lua attracted me because almost all its features are optionnal and can be cut (all lib modules, the Lua compiler). In that project I see Lua as an environment more than as a language, and lualib modules are things I'd like to cut to keep the core the smallest possible (following an approach similar to that found in micro kernels based OSes) and then add and remove at runtime at the finest granularity level possible. That means that I'd like to be able to unload io, update my io.dll and reinject it in my environment. I think Lua is capable to do that with only small modifications.
It's a kind of personnal lifelong project, I'm just trying to reuse the existing to save time, and sometimes tweaking what I have may be faster than spending time on google.
Doub.
-----Message d'origine-----
De : lua-bounces@bazar2.conectiva.com.br [mailto:lua-bounces@bazar2.conectiva.com.br] De la part de Mike Pall
Envoyé : 11 avril 2006 14:23
À : Lua list
Objet : Re: LuaThreads with LuaJIT (and maybe lua_tcc)
Hi,
Jerome Vuarand wrote:
> I'm working on a project that absolutely require premptive
> multithreading (multiple hardware threads are available) and some good
> runtime performance.
Then LuaThreads is not what you want. Apart from performance reasons (see below) there is a serious limitation: there is only a single lock around the Lua core. This means that only one thread at a time can execute Lua code. A thread can only run in parallel if it is executing C code which does _not_ call back into the Lua core (i.e. blocking in an I/O operation or some CPU bound C code).
I suggest you look into the mailing list archive for other approaches. You can use multiple Lua universes and connect them with message queues. Or you can use helper threads to do some isolated CPU bound operations in C code (only accessing the Lua core at the start and end).
Or you can use purely non-preemptive coroutines. It's inherently single-threaded, though. This is sensible for most I/O bound apps. You can run an app multiple times if it is CPU bound or just rely on other processes keeping all CPUs busy. Avoids the "mutex hell" of preemptive programming, too.
[Note that all of this is not a flame against LuaThreads. It's an inherent limitation of the concept and not the implementation.]
BTW: There is another approach which avoids most of the lock overhead. But it requires active cooperation on the C side and you can't use the current lua_lock/lua_unlock macros:
Basically the universe lock is held all the time, even when
crossing the Lua/C boundary. All I/O operations which could
potentially block need to be wrapped with an unlock before the
operation and a lock after the operation. Ditto for very CPU
intensive operations (like an RSA computation). This means you
need to modify io.* and any other external library which may do
some I/O (like LuaSocket).
Then you can either choose to use active preemption (requires
explicitly calling a no-op function which unlocks/locks) or
modify the main VM loop to unlock/lock after a certain number
of bytecodes. The former is easier for I/O bound code and you
can avoid locking global objects, too.
This is basically the same as the Python GIL approach. See
their archives for a discussion of the advantages and
disadvantages.
> I use custom Makefiles and was used to build a lua.dll and lualib.dll
> pair instead of a single lua50.dll. With Lua 5.1 I had to patch some
> files to allow seperation of core and lib.
Umm, why? There is no functional reason to do so. That's why this was dropped for the Lua 5.1 Makefiles.
If you really want to keep backwards compatibility to Lua 5.0 (I don't see the point for a new project), then it's considerably easier to change the Lua 5.0 Makefiles to use a single library.
> - did somebody achieved to make LuaThreads and LuaJIT coexist in the
> same build (even experience with 5.0.x would help me) ?
This is a lot of work. You'd need extensive modifications to LuaJIT to catch all cases where the core is left/entered or where the lock needs to be released temporarily for loops.
> - are there some expected fundamental issues or incompatibilities that
> would theoretically prevent me from using LuaJIT and LuaThreads
> together ?
LuaThreads may seriously slow down your application because of the excessive mutex overhead. Every C function needs a few calls back into the Lua core and each of them locks/unlocks the mutex.
Just registering the standard Lua libraries (luaL_openlibs) requires more than 1100 locks+unlocks! The heavy lock contention is bad enough for single CPUs and will slow everything to a crawl on multi-processor machines.
LuaJIT is there to speed up your application. Using it together with LuaThreads would be rather pointless since you'd loose much of the gain.
> - did somebody achieved to make LuaJIT and lua_tcc coexist ? (I
> haven't tried yet since I have problem with tcc relocation, but I
> guess two relocating runtime compilers in the same dynamically linked
> process may not like each other)
I have not tried, but I do not see a problem with coexistence.
Both compilers manage memory on their own and should not get into conflict. But read Javier's post, too.
> - did someone achieved to seperate LuaJIT core and lib code ?
See above. IMHO there is no point in trying. You need both anyway.
Bye,
Mike