This project is read-only.

First off thanks for the lib it's simple and looks great .. but

Jan 14, 2013 at 10:25 AM

I'm literally just about an hour into integrating this into my game and am getting really nice looking results but have just tested a first pass onto the xbox and am noticing a lot of regular collections from the GC.


scanning the code I've seen that the lib is making quite a few System.Array allocations inside DrawClippedFov on the render helper. (and presukably may also be elsewhere)

My question is is this an issue you're aware of and is a patch in the works basically (other wise I'll leap in and clean up my local copy of the source I've grabbed from here :) )

cheers again for the lib though it really is easy to use and looks pretty epic :)

Jan 14, 2013 at 10:54 AM

if you're interested I've tracked down a few of the culprits and altered the code to reuse single instances of the arrays as below (set the project to allow unsafe code and also use the "unsafe" keyword in the method signature to get this to work.)


                //resue existing array to remove allocations everyframe
                fixed (VertexPositionColorTexture* verticiesPointer = vertices)
                    VertexPositionColorTexture* vertexPointer = verticiesPointer;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 1;
                    vertexPointer->Position = new Vector3(ccw, 0);
                    vertexPointer->TextureCoordinate = ccwTex;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 2;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 3;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 4;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 5;
                    vertexPointer->Color = color;

                    vertexPointer = verticiesPointer + 6;
                    vertexPointer->Position = new Vector3(cw, 0);
                    vertexPointer->TextureCoordinate = cwTex;
                    vertexPointer->Color = color;

//                vertices = new[]
//                           {
//                               new VertexPositionColorTexture {Position = Vector3.Zero, Color = color, TextureCoordinate = new Vector2(0.5f, 0.5f),},
//                               new VertexPositionColorTexture {Position = new Vector3(ccw, 0), Color = color, TextureCoordinate = ccwTex},
//                               new VertexPositionColorTexture {Position = new Vector3(-1, 1, 0), Color = color, TextureCoordinate = new Vector2(0, 0),},
//                               new VertexPositionColorTexture {Position = new Vector3(1, 1, 0), Color = color, TextureCoordinate = new Vector2(1, 0),},
//                               new VertexPositionColorTexture {Position = new Vector3(1, -1, 0), Color = color, TextureCoordinate = new Vector2(1, 1),},
//                               new VertexPositionColorTexture {Position = new Vector3(-1, -1, 0), Color = color, TextureCoordinate = new Vector2(0, 1),},
//                               new VertexPositionColorTexture {Position = new Vector3(cw, 0), Color = color, TextureCoordinate = cwTex,},
//                           };

Jan 15, 2013 at 2:34 PM


Thanks for the compliments!

We're aware of the GC collections. While I wanted to make sure Krypton works on the XBOX, I never actually set down to do extensive XBOX-focused performance boosts.

On Windows, GC collections are extremely fast, so I didn't pay much attention on them. On the XBOX, however, GC collections are significantly slower, so attempting to re-use allocated memory is obviously a great idea. We simply got too busy.

Other places which may be optimized are foreach loops. .NET foreach loops simply call GetEnumerator() on the collection, and iterates over each item. Each call to GetEnumerator returns a new instance of an Iterator, and therefore allocated memory which will need to be collected sooner than later, since it's very short lived.

Replacing all of the foreach loops with array indexing for loops will also reduce the number of garbage collections.

There's also a few places in code where the flyweight pattern could be used (much in the same way you're doing with this quad).

I realize this project is hosted on codeplex, and no-one REALLY knows how to use codeplex, but if you make any significant improvements to performance, I'd like to see them and possibly integrate them. Just let me know, and I'll give you me e-mail address or something ^.^.

Jan 16, 2013 at 9:16 AM
Edited Jan 16, 2013 at 3:37 PM

Hey man

Thanks for getting back so quick. The compliments are entirely justified as after a couple of days of banging away at the performance problems (used as many unsafe pointer iterators as I could, used the caching trick posted here about a year ago on the vertex and index arrays plus added a noddy culling strategy on the list of hulls the render helper uses) the amount of depth this has added to my game is just amazing. I'm really pretty excited about it tbh. so thanks again for the lib (was a shame I ended up having to sink so much time optimising it but in fairness I would've spent about a month having to learn the shader code to do this myself so I'm still a big winner here.)

anyhoo upshot is that after all of that work I'm now back to my steady 60 fps. about 10 static lights plus 2 moving with playership and around 300 shadow hulls (though when culled usually c. 90 or so in view). per level and this is a twin stick shooter (set in a dungeon - so is kind of a guantlet like afair with twin stick mechanics and light puzzling) - I have a live AI budget of 60 on screen and a shed load of CPU based particles so my engine is really sensitive to a bottleneck is the thing - but again am just glad I would work through it all.

Happy to drop you the hacked project.

But yeah - the shame was the shader portion performs just fine - ALL of the performance issues were just in the C# (lucky for me as I can blast through that fairly easily - but like I said I wouldn't know shit from shineola when it comes to best practice with HLSL so I'd have been stuffed.)

If you're after some tips about optimising large array access and iteration in high frequency code - the mercury particle engine is a pretty good example of how to minimise how much of a bottle neck it can be.


edit; just upped a video of it in action.

Feb 4, 2013 at 5:31 AM

That is awesome.

Thank you.

So much.

I am glad people are benefitting from this project. I really wish I had the time to put effort into optimizing the engine and whatnot.

When writing Krypton, I was focused on the design of the library more than I was the performance of the engine. I believe this was the right choice, because it allowed me to be very flexible with the development, and find the right patterns for creating something usable and reusable.

Krypton's shader is probably the best 2D lighting shadow out there, performance-wise. However, that's not to say it couldn't be improved. I don't know. I'm not an HLSL master or anything, I just had a good idea at some point (doubling up vertices and stretching them, rather than generating them on the CPU) and formalized it through this engine.
Feb 7, 2013 at 6:54 AM
Hi antonyg, I realize that xixonia is very busy, I'd be very much interested in the xbox performance fixes. Can you please upload it as a patch or somehow otherwise make it available?
Feb 7, 2013 at 7:42 AM
Edited Feb 7, 2013 at 7:47 AM
hacked version at link below. changes are mostly to the renderhelper and light2d classes. the largest bottleneck left is calls to drawuserindexedprimitives but I'm not up to changing the framework to allow static hull geometry and so use a vertex buffer instead.
Feb 8, 2013 at 6:13 PM
awesome, thank you! will check it out!