XNA/Xbox 360 memory management heads-up...
So... what's the deal regarding:
- Large block allocation (will it have a large object heap like the desktop version?)
- GC pauses times (do all threads halt during GC)?
Andy.
So... what's the deal regarding:
Andy.
I guess a lot of it is based upon the notion that the 360 runtime is based upon the .Net CF, but anyhow, the blog claims to be regurgitating the contents of his gamefest talk.
The original question might seem a little premature, but any development that takes place on the beta will have to be based upon this knowledge (structs vs classes, heap size and allocation profiles). Sadly, if the 360's memory manager is really mark and sweep compacting, this means the best coding strategy will differ between it and the PC.
Andy.
Could someone in the know clarify this?
Hi Andy.
We are doing some investigation work with Rico around clarifying these issues. We'll post more details when we get them.
Thanks.
Rico Mariani's main suggestion for dealing with the compacting garbage collector is essentially to try to make a large chunk of your data as static as possible and to use "handles" (eg. integer indexes) within that data to refer to objects as much as possible. Having most, if not all, of a game's data statically rather than dynamically allocated was pretty standard back in the days when a PC's memory was limitted and you couldn't depend on virtual memory to handle accidentally over-committing memory. On the consoles that was even more true. If you can keep your dynamic allocations to a small "froth" above a mostly static set of monolithic data allocations containing few pointer references then you should be able keep the cost of garbage collection to something comparable with the generational collector. It should also be a win with the generational garbarge collector, though not enough to make it worth the trouble if you don't have to support the Compact Framework.
I fully understand what you are saying, but why on earth implement a compacting GC on a device with 6 hardware threads and 512Mb of RAM? Messing around with block allocations negates all of the productivity benefit of managed memory, and I suspect using the handles will result in a huge array bounds check penalty, unless you do everything with unsafe C# pointers (in which case I might as well have called malloc and used C). I doubt you'll even be allowed unsafe code blocks on the 360 due to the security implications.
Lets see what the guys at MS have to say ...
Andy.
AndyL wrote:
I doubt you'll even be allowed unsafe code blocks on the 360 due to the security implications.
You're correct. 360 games using GSE will exist in their own little box with only safe access to outside resources.
pointer arithmetic. You just don't have any way to P/Invoke into native
code from the managed sandbox.
Regarding heap sizes, one thing to bear in mind is that the biggest
data in a game tends to be textures, vertex data, and sound waveforms.
These are GPU resources, and don't count towards Rico's managed heap
size (other than a tiny little managed resource header).
Even looking at AAA commercial games, it is surprising just how small
their working data set can be if you look only at the active CPU
objects, not counting all the GPU data!
The obvious answer is that they didn't implement a garbage collector for the XBox 360, they're just using the one from .NET Compact Framework as is. I don't think the array bound check penalty will be a problem for most games using the XNA Framework, it's just going to be an additional constant and predictable overhead of using managed code. This is different from the penalty caused by garbage collection which has the potential to cause stuttering and poor responsiveness even in games with low performance demands.
that works. It turned out that it was possible for us to support unsafe
code and pointers even inside a secure sandbox on Xbox!
Also, "Array bound check penalties" have not been a problem for managed code since the introduction of the IE4 java virtual machine. (Java is not C# of course but the technology is the basically the same.)
Many common cases don't require array bounds checking at all in the inner loop. For instance:
int[] array = GetMyIntArray();
for (int i = 0; i < array.Length; i++)
array[ i ] *= 4;
Does the code above need to check array bounds at all? No, it's guaranteed not to exceed the bounds and a smart jit compiler knows this.
Array bounds checking and other similar things WILL NOT slow down your game... writing too many vertexes and/or failing to cull geometry WILL slow down your game.
Beloved XBox360 has a unified memory architecture, right?
So we can surely create any kind of buffer or texture via a direct (somehow aligned) memory pointer, right?
Maybe we can set the base of a buffer on the fly to another location?
I think about pinning managed memory... ![]()
Or do we have to use the DX9 (Windows) style, and have to lock and copy? This influences engine design largely...
Or maybe I am completely wrong here? ![]()