Coffeehouse Thread

38 posts

Interview with XNA Team

Back to Forum: Coffeehouse
  • User profile image
    W3bbo

    Minh said:
    W3bbo said:
    *snip*

    So you didn't use it based on philosophical grounds and not technical ones?

    Eh?

     

    I didn't use XInput because the gamepad I had to work with was a Logitech one. Which means I have to use either DirectInput or WinMM, and WinMM's API was the simplier and quickest to integrate into my code. There's no politics at all.

     

    If you're referring to my last sentance, that's unrelated. I was saying that people have successfully gotten the Xbox controller to work with DirectInput by providing their own drivers.

  • User profile image
    Minh

    W3bbo said:
    Minh said:
    *snip*

    Eh?

     

    I didn't use XInput because the gamepad I had to work with was a Logitech one. Which means I have to use either DirectInput or WinMM, and WinMM's API was the simplier and quickest to integrate into my code. There's no politics at all.

     

    If you're referring to my last sentance, that's unrelated. I was saying that people have successfully gotten the Xbox controller to work with DirectInput by providing their own drivers.

    Oh OK. I misunderstood. If your logitec controller is way more sophisicated than the Xbox controller, then you have to avoid XInput.

  • User profile image
    BitFlipper

    Minh said:
    BitFlipper said:
    *snip*

    I would think this is an overkill / pre-mature optimization. They say the Xbox GC at 1MB allocations, so if you have a small string, say 50 chars, then your periodic GC runs at 1,000,000 bytes / (50 chars * 2 unicode bytes / char) = 10,000 strings / 60 strings / sec / 60 sec / min / 60 min / hr = 2.78 hrs.

     

    So, if all your game does is the fps string, then GC will run once every 3 hrs... Of course, that won't be all it does, but you get the idea.

     

    Optimizations you could do is only update the fps once every second, instead of 60 times a sec... Or there's a SpriteBatch.DrawInt32 user routine out there that doesn't use strings... Or do a pre-compute string table...

     

    The idea is to mitigate the effect of GC, not elimitate it. If you can keep GC to a manual process you do that can't be seen by the player, then that's a huge win.

    You are correct that if the only thing my game did was print an fps string to the screen, that would probably not be an issue. Throw in scene management, AI, collision detection, physics, weapons, enemies, sound, particle effects, a HUD, etc etc and things get a bit more complex. A game is very dynamic as there is a lot of interaction between objects and things come and go continuously (think of bullets, etc). Obviously you re-use objects as much as possible, but that is not the only source of allocations. It is possible to delay the inevitable GC, but that is all you can do - delay it.

     

    Right now I am working on my collision detection algorithms. I have a relatively simple scene that I use to test it with. I am getting around 2000 - 3500 fps with this simple scene (on the PC). Looking at my code, I can't see an obvious place where memory is being allocated, yet the memory goes up roughly ~200KB every second. Granted, at those frame rates, even a small allocation would quickly add up (and it is not the fps counter - I checked that). This means I need to go and dig into the code and see what is going on. Now if I have a more complex scene, the fps would obviously drop, but at the same time the complexity would go up so I imagine the allocations per sec would remain more or less the same. And as the object graph gets more complex, a GC will become slower. I have not seen issues simply because currently my object graph is too simple - the GC can very quickly do a collect. But other people are running into this problem - just go to forums.xna.com and search for GC. Edit: "garbage" is a better term to search for here.

     

    My point is - we should not have to worry about this (within reason). Why do we need to worry about the internal memory allocation details of the .Net classes when we use a high-level language?

  • User profile image
    rhm

    BitFlipper said:
    Minh said:
    *snip*

    You are correct that if the only thing my game did was print an fps string to the screen, that would probably not be an issue. Throw in scene management, AI, collision detection, physics, weapons, enemies, sound, particle effects, a HUD, etc etc and things get a bit more complex. A game is very dynamic as there is a lot of interaction between objects and things come and go continuously (think of bullets, etc). Obviously you re-use objects as much as possible, but that is not the only source of allocations. It is possible to delay the inevitable GC, but that is all you can do - delay it.

     

    Right now I am working on my collision detection algorithms. I have a relatively simple scene that I use to test it with. I am getting around 2000 - 3500 fps with this simple scene (on the PC). Looking at my code, I can't see an obvious place where memory is being allocated, yet the memory goes up roughly ~200KB every second. Granted, at those frame rates, even a small allocation would quickly add up (and it is not the fps counter - I checked that). This means I need to go and dig into the code and see what is going on. Now if I have a more complex scene, the fps would obviously drop, but at the same time the complexity would go up so I imagine the allocations per sec would remain more or less the same. And as the object graph gets more complex, a GC will become slower. I have not seen issues simply because currently my object graph is too simple - the GC can very quickly do a collect. But other people are running into this problem - just go to forums.xna.com and search for GC. Edit: "garbage" is a better term to search for here.

     

    My point is - we should not have to worry about this (within reason). Why do we need to worry about the internal memory allocation details of the .Net classes when we use a high-level language?

    Yeh, it's stupid to say use a managed language because it saves you from having to concern yourself with memory management, and then tell programmers that actually they do have to tear their hair out worry about every single allocation because if they don't the GC is going to come and freeze up their gameloop while it examines THE WHOLE HEAP.

     

    It's like you're actually worse off than the C++ programmer who only has to worry about freeing memory up at the right time and in the case of memory that's only needed for temporaries during the processing of a single frame, they can use a custom allocator that discards everything in one go at the end of the loop.

  • User profile image
    magicalclick

    BitFlipper said:
    magicalclick said:
    *snip*

    The float is a value type so it is not a problem in this case. But calling float.ToString() allocates a string, which is a ref object. You say fps.ToString() is released right after the line ends. Released to where? This has everything to do with garbage.

    float.ToString()?

     

    return values from a function call is stored in the call stack or something right? It is push right at return and pop right at caller line. It is just C++. You don't need to release anything for that in C++. Unless XNA is so much different from C++ and C# that we will have to release every single return primitive? String is a special primitive that will be released automatically in C++. I am just talking about C++. And there is no additional action needed to be done in C++. C# is just doing the same as C++ on this part.

     

    In C++, if you return an object, you don't release until you want to kill it. In C#, you can release it manually or wiat for GC. In XNA, I assume it is C#.

     

    Leaving WM on 5/2018 if no apps, no dedicated billboards where I drive, no Store name.
    Last modified
  • User profile image
    Minh

    BitFlipper said:
    Minh said:
    *snip*

    You are correct that if the only thing my game did was print an fps string to the screen, that would probably not be an issue. Throw in scene management, AI, collision detection, physics, weapons, enemies, sound, particle effects, a HUD, etc etc and things get a bit more complex. A game is very dynamic as there is a lot of interaction between objects and things come and go continuously (think of bullets, etc). Obviously you re-use objects as much as possible, but that is not the only source of allocations. It is possible to delay the inevitable GC, but that is all you can do - delay it.

     

    Right now I am working on my collision detection algorithms. I have a relatively simple scene that I use to test it with. I am getting around 2000 - 3500 fps with this simple scene (on the PC). Looking at my code, I can't see an obvious place where memory is being allocated, yet the memory goes up roughly ~200KB every second. Granted, at those frame rates, even a small allocation would quickly add up (and it is not the fps counter - I checked that). This means I need to go and dig into the code and see what is going on. Now if I have a more complex scene, the fps would obviously drop, but at the same time the complexity would go up so I imagine the allocations per sec would remain more or less the same. And as the object graph gets more complex, a GC will become slower. I have not seen issues simply because currently my object graph is too simple - the GC can very quickly do a collect. But other people are running into this problem - just go to forums.xna.com and search for GC. Edit: "garbage" is a better term to search for here.

     

    My point is - we should not have to worry about this (within reason). Why do we need to worry about the internal memory allocation details of the .Net classes when we use a high-level language?

    post your code.

     

    I did a collision detection engine where the static mesh are created at load time, and shouldn't incur any game time pressures to the GC.

     

    You probably got a ref object in there somewhere that you think is a value object

  • User profile image
    BitFlipper

    magicalclick said:
    BitFlipper said:
    *snip*

    float.ToString()?

     

    return values from a function call is stored in the call stack or something right? It is push right at return and pop right at caller line. It is just C++. You don't need to release anything for that in C++. Unless XNA is so much different from C++ and C# that we will have to release every single return primitive? String is a special primitive that will be released automatically in C++. I am just talking about C++. And there is no additional action needed to be done in C++. C# is just doing the same as C++ on this part.

     

    In C++, if you return an object, you don't release until you want to kill it. In C#, you can release it manually or wiat for GC. In XNA, I assume it is C#.

     

    Really that is not how memory works in C#. It is not like C++ at all. Calling float.ToString() absolutely allocates a string, and even if you don't store it, it only means that it is not rooted  any more. It is still allocated until the GC determines that it isn't (there's the problem right there) and only then will it be released.

  • User profile image
    Charles

    BitFlipper said:
    magicalclick said:
    *snip*

    Really that is not how memory works in C#. It is not like C++ at all. Calling float.ToString() absolutely allocates a string, and even if you don't store it, it only means that it is not rooted  any more. It is still allocated until the GC determines that it isn't (there's the problem right there) and only then will it be released.

    Guys.... This thread is for asking questions of the XNA team, not arguing about your position/percpetion/opinion/understanding of managed code, etc...... Please..

    C

  • User profile image
    BitFlipper

    Minh said:
    BitFlipper said:
    *snip*

    post your code.

     

    I did a collision detection engine where the static mesh are created at load time, and shouldn't incur any game time pressures to the GC.

     

    You probably got a ref object in there somewhere that you think is a value object

    Well there is just way too much code to post it (and I don't really think this is the correct thread for it). I am sure I am not allocating ref objects during the game loop as I have carefully stepped through it looking for exactly that. The more likely cause is that I am using the .Net or XNA classes in such a way that garbage is created that I am unaware of. This is a minefield where innocent "mistakes" lead to garbage. Examples of things that could create garbage during the game loop:

    • Calling anonymous methods or closures.
    • Setting/clearing delegates or event handlers.
    • Using an enum as a key in a dictionary. Simply doing a lookup creates garbage in this case.
    • Doing "silly" things like wanting to create strings using "+" or "string.Format, etc.
    • Adding/removing items out of a LinkedList. It is very common to have objects added/removed from linked lists in the game loop. So now you have to roll your own linked list, or use something other than linked lists.
    • Accessing value types via an interface will cause them to be boxed (was not aware of this).
    • Some enumerators create garbage. Good luck figuring out which ones do and which ones don't. Quick: Does foreach() on a Dictionary ValuePair create garbage? Often it seems safer just to fall back to for() if you are unsure (where the collection allows this).
    • Using yield in order to enumerate objects.
    • And who-knows-what-else happens behind the scene as you use the built-in .Net classes.

    The point is, you might not create garbage while using your own classes/structs, but there are many cases where simply doing things that look innocent causes garbage to be created.

     

    This is a quote from Shawn Hargraves (works on XNA Game Studio at MS):

     

        You can achieve good performance by avoiding allocations, so the garbage collector will never run. This works regardless of how complex your heap may be.

        You can also achieve good performance by keeping your heap nice and simple, so the garbage collector will finish quickly. This works regardless of whether you allocate memory during gameplay.

        But you cannot achieve good performance by mixing these two approaches! There is little to be gained by allocating only a medium amount of memory and having only a medium complex heap. That will produce a game which has a medium size glitch every medium number of seconds.

        If your goal is to avoid garbage collection glitches altogether, you must pick just one path and follow it to the bitter end.

     

    This just isn't ideal. An incremental GC would help since then you don't need to worry about creating some amount of garbage (within reason) at each frame, no matter how large your object graph is. Having to pick between one of the two above approaches and then ensuring that you stick to it really complicates things. Java has an optional low-pause incremental collector, why not .Net?

     

    EDIT: @Charles: Sorry, only saw your post after I posted. Will stop posting now. If someone wants to discuss the details further, we can create another thread.

  • User profile image
    rhm

    Charles said:
    BitFlipper said:
    *snip*

    Guys.... This thread is for asking questions of the XNA team, not arguing about your position/percpetion/opinion/understanding of managed code, etc...... Please..

    C

    So to boil it down into a question for the XNA team: Will the XBox version of XNA ever get to run the desktop CLR or see significant improvements to the garbage collector on the current runtime?

  • User profile image
    magicalclick

    BitFlipper said:
    magicalclick said:
    *snip*

    Really that is not how memory works in C#. It is not like C++ at all. Calling float.ToString() absolutely allocates a string, and even if you don't store it, it only means that it is not rooted  any more. It is still allocated until the GC determines that it isn't (there's the problem right there) and only then will it be released.

    I see, so string is not a special premitive in C#, while it is special premitive in C++. Got it.

    Leaving WM on 5/2018 if no apps, no dedicated billboards where I drive, no Store name.
    Last modified
  • User profile image
    W3bbo

    magicalclick said:
    BitFlipper said:
    *snip*

    I see, so string is not a special premitive in C#, while it is special premitive in C++. Got it.

    std:string isn't a special primitive in C++ either. It's just a class wrapper around a null-terminated array of char (or wchar_t or some other type if you're using STL). In .NET String is a "special" class in that it can be treated as a const and has special in-memory behaviour (see String Internment) but whatever.

     

    Anyway, Charles said this thread is about questions to pitch to the XNA guys, not each other.

  • User profile image
    aL_

    when will xna have better support for dx11 and windows programming? i realize xna is mostly for xbox but it seems so strange to not support the latest (or even second latest) version of the graphics framework of the largest gaming platform in the world Tongue Out

    phones will also get more advanced capabilities soon..

     

    in general i think microsoft should market directx more agressivly to developers, and xna is agreat way to do that 

    (more directx/xna content/tutorials on c9 would also be awsome btw Smiley

     

    also, major BUMP on @bas's question on kinect support Wink 

  • User profile image
    BitFlipper

    If anyone wants to discuss the issues with the GC any further, I created a thread here.

  • User profile image
    Bass

    When will you support Mac OS X and Linux?

  • User profile image
    Cream​Filling512

    Are there any plans to improve the JIT compiler for XNA on Xbox, GC, and other core runtimes?  Some basic changes like more aggressive method inlining would go a long way.  Currently you have to write messy code to get the best performance .

  • User profile image
    Ian2

    CreamFilling512 said:

    Are there any plans to improve the JIT compiler for XNA on Xbox, GC, and other core runtimes?  Some basic changes like more aggressive method inlining would go a long way.  Currently you have to write messy code to get the best performance .

    How far ahead are you with the XNA build for XBOX 3?  (no harm in trying)

  • User profile image
    battlebottle

    i'll add i'd like to see do they have any thoughts on improving how developers have to deal with the GC in future.

     

    also would like to know where they see XNA going in the future. Though that's a pretty obvious question. but it's interesting seeing now that XNA is the only platform for developing high end games on wp7, given that XNA was originally a project primarily aimed at indie developers, it's now been given a lot more responsibility to be a top class platform for big developers to produce games too. Not that i think there's one thing wrong with that. I think it's exciting for game making tools used by big developers to make high end games are accessible and usable by the humble bedroom programmer.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.