[Lua] Multi threading Lua...

Started by
24 comments, last by ZealGamedev 13 years, 6 months ago
Quote:
Spend some time thinking about string interning and cross-coroutine upvalues, and you'll get a better idea as to why it's necessary.


Well lets just focus on "local t = {}", because that also seems to be crashing too. Why is a local allocation, that is only visible to the calling thread, not thread safe? *Why CANT it be thread safe I guess is the real question.

Quote:
As for garbage collection, if you want to try implementing a thread-safe, lock-free, incremental generational garbage collector, well.... it would be a very useful thing to have, for Lua and for pretty much any other language out there.


Well for my case, it would be sufficient if each state simply tracked its own allocations, and had its own GC. I dont plan to have these threads ever write to any true 'globals', I only want to read them.
Advertisement
It sounds like you have very specific needs, and little patience for languages which do not specifically prioritize them over others' needs. I suggest that you write your own interpreter.
Quote:It sounds like you have very specific needs, and little patience for languages which do not specifically prioritize them over others' needs. I suggest that you write your own interpreter.


Really?

function doSomethingExpensive(gameEntity)	data = getReadOnlyGlobalData()	...	gameEntity.localState = somethingNewend


...Is that "very specific"? Seems pretty generic to me. And VERY useful too (especially for games). There are a million cases where you might need to run a complex function on all your game entities. And if that function only relies on some thread safe data, and a unique output buffer, wouldnt it be nice to run at 8x speed?

And its not a "lack of patience", I am just surprised that Lua (the king of game scripting languages) doesnt support something like this.
Quote:Original post by ZealGamedev
From http://lua-users.org/wiki/ThreadsTutorial
Quote:One way is to call lua_open. This creates a new state which is independent of the states in other threads. In this case, you'll need to initialize the Lua state (for example, loading libraries) as if it was the state of a new program. This approach eliminates the need for mutex locks (discussed below), but will keep the threads from sharing global data.

The other approach ...
^^Doesn't this sound like what you want? Completely seperate lua states without requiring mutexes?

To share the read-only global input data between each state, instead of putting it in a Lua global, you access it through a C/C++ function that you've bound to Lua.

For more info, check out the docs from the BitSquid engine, specifically section 3.5 and 3.7: http://www.bitsquid.se/files/Lua API.pdf
Quote:Original post by Sneftel
This is why people who need preemptive threading in Lua tend to use separate global states.
So, isn't the answer to his problem to explain how to use separate global states? i.e. tell him how to do this in Lua, instead of how to do it the wrong way in a hypothetical new language that he'll develop for the purposes of not learning how to use Lua properly? Fuck...
Quote:
^^Doesn't this sound like what you want? Completely seperate lua states without requiring mutexes?


Each thread/state needs to access a shared set of read only data (updated at a different point in the frame). Plus having to load the entire lua library, and all my game scripts for each thread seems a tad inefficient (especially when were talking about scaling to n cores).

Quote:
To share the read-only global input data between each state, instead of putting it in a Lua global, you access it through a C/C++ function that you've bound to Lua.


A lot of data (most all of the game specific data) doesnt really belong in C (C cant really do anything with it). So I am trying to avoid the overhead of moving large amounts of data to/from lua/c. Ill take a look at that link you posted though...
Quote:Original post by ZealGamedev
Each thread/state needs to access a shared set of read only data (updated at a different point in the frame).
Sorry, I edited in more info on this above. Store the 'global' data in the host program, not in Lua.
Quote:Plus having to load the entire lua library, and all my game scripts for each thread seems a tad inefficient (especially when were talking about scaling to n cores).
Often, greater thread/core isolation is paid for by 'wasting' RAM. Would you rather use more RAM or use more mutexes? ;)
[edit]Also, the BitSquid guys have written several PS3/360/PC engines, so I'd trust them on this trade-off =D
Lua was never designed to be truly multi-threaded. But it is designed to not depend on *real* global state (there are no mutable globals in Lua.dll), independent lua_States can be safely used in different threads.

This situation is a lot better than many scripting languages, Google "global interpreter lock" for more information.

Depending on what you are doing, you might be able to avoid loading all scripts into each state, and avoid copying excessive data into each.
Quote:Original post by Hodgman
For more info, check out the docs from the BitSquid engine, specifically section 3.5 and 3.7: http://www.bitsquid.se/files/Lua API.pdf
Quote:Original post by Sneftel
This is why people who need preemptive threading in Lua tend to use separate global states.
So, isn't the answer to his problem to explain how to use separate global states? i.e. tell him how to do this in Lua, instead of how to do it the wrong way in a hypothetical new language that he'll develop for the purposes of not learning how to use Lua properly? Fuck...
I did, like, eight replies up. (Lua Lanes.) I'm done here.
Quote:
I did, like, eight replies up. (Lua Lanes.)


Mentioning Lua Lanes (in the super awesome not at all condescending way that you did) hardly addressed the questions I was asking.

Quote:
I'm done here.


Awe come on dont be like that.

@Hodgman

Thanks for that bitsquid link, I just read their docs... I had contemplated solving this problem by moving all my 'global game data' from Lua to c, but I am still a tad hesitant for the following reasons - Currently the only data I manage in C is data that 'belongs' to C systems (meshes for the renderer, bodies for the physics system, ect...), while the 'game specific' data (health, ammmo, ect...) exists in Lua. Since the C systems (Graphics engine, Physics engine) have no concept of health or ammo, this makes sense. The 'game specific' systems tend to exist in Lua, so thats where I would like to keep the 'game specific' data.

However, the bitsquid guys make a couple good cases for why you may want to store all your Lua data in C. It gives you tighter control over memory allocation, and can reduce the strain on the Lua GC. So its definitely something I am considering more seriously now... It would sure make this damn problem a lot easier to solve no doubt!

But just out of curiosity, does anyone know the logic/benefit behind why even LOCAL allocations are not thread safe? Take my original example form the first post, and forget about globals. If you simply allocate a local table, the thing freaks out. I thought lua_newthread() gave you a completely independent and therefore thread safe stack at least?



Tables are garbage collected, they aren't allocated on the stack. A reference to them is placed on the stack. Lua doesn't try to make such allocations thread safe. Another possible issue is hooks. Lua has some memory and debug hooks, some of them might be triggered by such an allocation. These would have to be thread safe too.

This topic is closed to new replies.

Advertisement