Page 1 of 1

Do these memory management techniques work in Lua?

Posted: Tue Jul 02, 2019 6:37 pm
by Bogdan705
I managed once again to fall down the rabbit hole of internet articles and eventually stumbled upon a few articles regarding two memory management techniques : something called Data Locality and Object Pools

While the code itself is written in a C language ( can't tell which one because I have no experience with C/C#/C++ ), I'm wondering if these methods can help boost performance, especially since the CPU and such is voodoo magic for me. My guess is.. kinda not? the Object Pool part does seem really useful, but the Data Locality, not so much ... afaik all variables in Lua are already pointers, and the article for Data Locality makes me believe pointer speed issues are a C specific thing, thus rendering an implementation in Lua kinda... pointless

BADUM TSS

Now, in all seriousness, can someone please offer some clarification about this topic?

Re: Do these memory management techniques work in Lua?

Posted: Tue Jul 02, 2019 7:08 pm
by zorg
First, your links are errorenous, you should delete the "//url" from the end of them;
Second, we could also add the SoA vs AoS debate into the mix as well, or whether ECS is more performant than OOP or not.

Anyway, you need to know that Löve by default uses LuaJIT, which is a just in time compiler that turns lua code into efficient bytecode that can be (nearly) as performant as a C implementation, in a lot of cases.

As you said yourself, lua variables aren't exactly laid out contiguously in memory as you could do with more "low-level", or at least more direct languages like C or C++, and tables are another beast altogether; unless you're utilizing the FFI (foreign function interface) of the JIT compiler itself, thereby defining C variables and, more importantly, arrays and structures, you won't get too much data locality otherwise.

As for pooling, there are gains to be had from not creating new lua tables each frame for instance, and reusing them, and their elements as well; maybe even creating as many as you'll potentially need at the beginning - i know there are people who argue for this verily.

Still, unless you want to implement something really heavy, i'd say just don't worry about it until it gets to be a problem, and just code instead of thinking about the many ways your code would potentially be unperformant.

Re: Do these memory management techniques work in Lua?

Posted: Tue Jul 02, 2019 7:22 pm
by Bogdan705
I apologize for the links and broad question. Thank you for your answer!

Re: Do these memory management techniques work in Lua?

Posted: Tue Jul 02, 2019 9:32 pm
by pgimeno
AFAIK, LuaJIT arrays are contiguous memory portions of 64-bit elements, so there might be some benefit in data locality (in some applications).

Re: Do these memory management techniques work in Lua?

Posted: Wed Jul 03, 2019 5:57 am
by raidho36
Note that this only applies to basic types. Strings, tables, cdata and userdata are separate objects in the memory, and table only contains pointers to them.

Pointer access speed is definitely not C-specific. Beyond slow algorithms, it's the #1 cause of bad performance in every language in existence. The reason is purely technical: data by pointer can reside anywhere in the memory, thereby forcing random access. Because "random access" memory is actually a sequential storage and is optimized for sequential access, this causes processor stall as it waits on the memory to resolve the address and return new data. If it were to simply read an adjacent array element, the memory unit would simply stream the data from the next memory cell sequentially back to the CPU, without having to actually accept new address locations and resolving them, which is very fast. If the data fits on the CPU cache, there probably won't be RAM access at all and it'll work the fastest, but CPU caches are tiny and you're not in any control of it whatsoever*, and therefore these are hard to work with. Having a layer of a high level language inner workings on top of your code makes all of the above a little worse yet.

LuaJIT has a powerful trace compiler that can often enough optimize away temporary allocations, so pooling might not be needed. Either way, pooling comes with a sizeable performance impact so you should balance using object pools vs. garbage collection overhead. Keep in mind that live objects add up to GC book-keeping costs.

Data locality is basically impossible to achieve in any language with automatic memery management, however with LuaJIT specifically it still works very fast if you access arrays in linear fashion, even if individual elements are spread across the memory.

*technically you could do things like flushing the cache, if you want to make your program run worse