[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Avoiding FFI- allocations + using SSE-vectors
- From: Joshua Jensen <josh.jjensen@...>
- Date: Mon, 06 Feb 2012 09:38:34 -0700
----- Original Message -----
From: David Given
Date: 2/6/2012 6:44 AM
For the games we developed with the reference counting system in LuaPlus
(or for regular Lua, LuaRC), it solved a variety of woes _automatically_.
Mike Pall wrote:
Reference counting (RC) has plenty of practical problems. One key
aspect is that the impact is hard to measure, since the overhead
is spread out all over the code. Some issues, like excessive
number of writes, cache pollution, unbounded latency vs. delayed
free, etc. can be solved with more complex variants of RC.
In an earlier life I worked on an object-oriented operating system where
all objects were reference counted.
Never, never again.
Not *only* does it have the problems described above, it's also
incredibly brittle and easy to break. Forgetting to take a reference or
drop a reference can lead to obscure and hard-to-find bugs. And it makes
the code verbose and difficult to read. *And* since dropping a reference
can conceivably lead to the object being destroyed then and there, if it
was the last reference, it means you have to be really careful when
references get dropped.
I've discussed the performance benefits for more memory intensive
scripts on the list before. I can look them up, if you care.
You refer to issues where the object is destroyed then and there. Well,
having deterministic finalization is really cool. If I had a Lua object
referring to an open file, I know that the file object's __gc method is
going to be called as soon as the object falls out of scope. The file
won't stay open until some point in the future when the garbage
collector kicks in, leading to unpredictable and hard to find bugs!
Deterministic finalization _prevents_ these bugs from occurring.
I ran into a few problems with reference counting within Lua.
1) Cycles cannot be detected, and the full Lua garbage collect has to be
run. In my code, there were no cycles, so we never ran the Lua garbage
collector during 'real-time' gameplay.
2) Reference counting has a cost, and it slows down the VM across the
board. This was not really measurable for us, though. Running the Lua
garbage collector always resulted in **major** cache misses as it
visited objects spread across the memory spectrum. Incrementing and
decrementing a reference count may possibly result in a cache miss, but
it probably doesn't, given that the object was generally just accessed
and in the cache anyway.
3) I never fully implemented supported for weak objects. I just let the
garbage collector do its thing.
A generational collector may be as effective as a reference counting
system, but I doubt it. I hope to be proven wrong, though. In my
experience, the biggest issue I have dealt with in games using Lua is
with the time to garbage collect objects. Lua 5.1's incremental
collector is a step forward, but you still run across blog posts where
game developers hacked the GC to abort within a certain period of time.
Or they force delayed garbage collection until a certain point. The
list goes on.