Quake2 allocblock #106

Open
wants to merge 2 commits into from

2 participants

@pmer

Hello,

I am just presenting this here so that a final statement can be made on whether to include this or not.

This branch implements Quake 2's block allocator, which improves Gosu's speed with allocating images.

Cheers,
Jamer

@jlnr
The Gosu Library member

I recently realized that Q2's requirements are not necessarily the same ones as ours. Does Quake 2 ever deallocate stuff and allocate new pieces? I have a running production setup where images are freed and new ones are loaded all the time, without too much leaking (due to fragmentation) so far.

At the very least, I'd like to try and see how the new allocator handles these situations. I'll try to come up with a test program.

@pmer

Good question! Right now, each vertical column of memory is tallied as being occupied up to the bottom-most texture occupying it. If a texture in the middle of the column is freed, it won't be recognized until everything below it is, too. Although no memory is permanently lost, it can present suboptimal cases for long-running programs that recycle resources over time.

I tested a few applications, but I didn't write a benchmark for it or anything. I didn't notice anything substantial in my program, though, probably because my textures only use about 8 MB of graphics memory. ;) For short games it probably doesn't matter too much. Bigger programs might have to worry about it, however. Can I ask what audience you are targeting with Gosu, or what your design goals are in considering this? I'm just trying to get a feel for where Gosu's head developer is coming from. :)

@jlnr
The Gosu Library member

So, a few thoughts after chatting with Seisatsu (and slowly getting closer to it on the To Do):

One could always fall back to the old algorithm after the first deallocation on a texture has actually happened. That would be better, in every case, than the current state of things.

Or to get fancy, one could use Carmack's algorithm but keep a vector of free (deallocated) places around that are filled up again with priority. Only once that list grows too big would it fall back to the current brute force.

@jlnr jlnr closed this Jan 14, 2012
@jlnr jlnr reopened this Jan 14, 2012
@jlnr
The Gosu Library member

Terava for iOS is the game that set the upper limit for what Gosu should do, and the lowest limit on hardware with the first iPhone, or at least iPhone 3G. (It is also the game that started Gosu, but that is a coincidence ;))

Terava, and every game that allocates data in a FIFO manner, will fragment heavily with Carmack's algorithm. And if you use a cache that keeps the most recently used N images around, it is easy to have a FIFO situation that would eat up infinite memory on the desktop as well.

Even if this is a rare case, it is painful for a game developer to prove that it won't happen.

@jlnr
The Gosu Library member

I have also been thinking about this whole thing and about why only we need a 2D allocator when the whole world has optimized 1D allocators already. Why does OpenGL have u/v parameters instead of just allocating VRAM?! So weird.

In both 2D and 3D gaming, it doesn't seem like anyone really uses the only advantage a 2D texture introduces - that you can draw arbitrary source rectangles from a texture. In every other way, just having a vram_malloc(w,h) would seem so much more practical for everyone.

I just had to get this out. :D

@pmer

Can't drawing arbitrary source rectangles also be done with clipping? (curious)

The block allocator issue really does feel like one of Gosu's largest implementation weak points to me. I wouldn't be surprised if kuehkookies' recent slow-down troubles[1] were related to this.

[1] http://www.libgosu.org/cgi-bin/mwf/topic_show.pl?pid=5509

@jlnr
The Gosu Library member

So what did you think about this approach:

Or to get fancy, one could use Carmack's algorithm but keep a vector of free (deallocated) places around that are filled up again with priority. Only once that list grows too big would it fall back to the current brute force.

Too complicated to be viable? I think the allocator should handle FIFO situations. The one on the boards was like an insane FIFO rotation, always allocating the same image while the GC tried to free as many old copies as it could.

@jlnr
The Gosu Library member

FWIW here's a public domain library for rect allocation here: https://github.com/nothings/stb/blob/master/stb_rect_pack.h

pmer added some commits Nov 19, 2011
@pmer pmer implementation of Quake 2's block allocator
As it stands, this code may be an order of magnitude or two faster than
the existing block allocation implimentation, with increasing gains for
large numbers of small images.
2dfca69
@pmer pmer abs(int) -> fabs(double) b332b45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment