The language seems very capable in most regards and has many attributes of
an excellent game scripting language, but it's garbage collection pauses
seem to be a showstopper flaw. In prototype code that does an amount of
realtime object creation that is reasonable for a current generation game,
i.e. around 100 object allocations per frame at 60 fps, I'm seeing pauses of
2-3 seconds that occur once every 5-10 minutes.
Is this a feature or a bug?
Obviously one can't ship an action game that hits a 5 second pause every
5-10 minutes!
Note that in this scenario the amortized time going to garbage collection
(under 3% of execution time) is totally acceptable. What's unacceptable is
that it all happens at once and makes the application appear to be locked
up. In a realtime app such as a game that attempts to run at 60 fps, it is
necessary to establish a realtime expectation on garbage collection overhead
(not a hard guarantee, but an expectation that we can count on being broken
only very infrequently), such as "the garbage collector will never use more
than 1 msec within any 10 msec period of time".
Also, out of curiosity, is this the same issue that causes the Visual C++
IDE to lock up for 5 seconds every 5-10 minutes? (I was assuming this was
related to the non-Microsoft Perforce source control integration we use, but
after experimenting with C# I wonder if this is an unavoidable aspect of
managed code).
The .NET framework is awesome and I really hope this isn't a fundamental
flaw of managed .NET code.
-Tim
in-line below
--
Phil Taylor
PM : DirectX SDK, Managed DirectX, Windows XP Inbox 3D screensavers, and a
few more bits and bobs.
http://msdn.microsoft.com/directx
This posting is provided "AS IS" with no warranties, and confers no rights.
"Tim Sweeney" <t...@epicgames.com> wrote in message
news:#sNvbJJMCHA.1988@tkmsftngp08...
> Does Microsoft take the possibility of using C# for game development
> seriously? It seems like it could be considered either as a gameplay
> scripting language or as a full-blown development language once DirectX9
> ships with full .NET support.
Yes to both.
We hope our wrapper layers' perf is such that folk would consider using
Managed DX for full blown development, not just tools and scripting.
>
> The language seems very capable in most regards and has many attributes of
> an excellent game scripting language, but it's garbage collection pauses
> seem to be a showstopper flaw. In prototype code that does an amount of
> realtime object creation that is reasonable for a current generation game,
> i.e. around 100 object allocations per frame at 60 fps, I'm seeing pauses
of
> 2-3 seconds that occur once every 5-10 minutes.
note that MDX avoids managed types, and thus avoids the managed heap and the
GC so we dont have this non-determinstic perf behavior.
its then up to each managed app writer how to handle using or not using
managed types and __gc.
the behavior you see, this is allocating app objects on the managed heap? or
allocating MDX objects?
>
> Is this a feature or a bug?
>
> Obviously one can't ship an action game that hits a 5 second pause every
> 5-10 minutes!
>
> Note that in this scenario the amortized time going to garbage collection
> (under 3% of execution time) is totally acceptable. What's unacceptable
is
> that it all happens at once and makes the application appear to be locked
> up. In a realtime app such as a game that attempts to run at 60 fps, it
is
> necessary to establish a realtime expectation on garbage collection
overhead
> (not a hard guarantee, but an expectation that we can count on being
broken
> only very infrequently), such as "the garbage collector will never use
more
> than 1 msec within any 10 msec period of time".
>
> Also, out of curiosity, is this the same issue that causes the Visual C++
> IDE to lock up for 5 seconds every 5-10 minutes? (I was assuming this was
> related to the non-Microsoft Perforce source control integration we use,
but
> after experimenting with C# I wonder if this is an unavoidable aspect of
> managed code).
these two will have to be handled by someone with deeper knowledge of the GC
and what the IDE is doing, I can only comment on MDX.
>
> The .NET framework is awesome and I really hope this isn't a fundamental
> flaw of managed .NET code.
>
> -Tim
>
>
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.375 / Virus Database: 210 - Release Date: 7/17/02
Hi Phil!
The managed DirectX9 layer looks GREAT, by the way - very clean and
straightforward. It's clearly going to be one of the stronger aspects of C#
and .NET programming.
> > The language seems very capable in most regards and has many attributes
of
> > an excellent game scripting language, but it's garbage collection pauses
> > seem to be a showstopper flaw. In prototype code that does an amount of
> > realtime object creation that is reasonable for a current generation
game,
> > i.e. around 100 object allocations per frame at 60 fps, I'm seeing
pauses
> > of 2-3 seconds that occur once every 5-10 minutes.
>
> note that MDX avoids managed types, and thus avoids the managed heap and
the
> GC so we dont have this non-determinstic perf behavior.
>
> its then up to each managed app writer how to handle using or not using
> managed types and __gc.
>
> the behavior you see, this is allocating app objects on the managed heap?
or
> allocating MDX objects?
The occasional pauses I'm seeing occur even when Managed DirectX isn't used
at all. My test app does a lot of object creation and dealing with mundane
arrays and strings, so it creates a lot of objects to garbage-collect.
-Tim
Like he said, MDX makes a strong point to avoid heap-allocated objects
(by sticking to structs and other value types, I assume) which avoids
the need for GCing often.
What you are experiencing is when you are using regular heap-allocated
objects (your every-day normal objects). The GC worries about these.
Supposedly, with MDX, since very few of the objects are allocated on
the heap, the GC won't have to worry much about those and the collection
period will only be a scant few milliseconds.
However, what I wonder about is if this will mean that all performance-
minded MDX apps will also have to follow all these rules. Programming
DirectX in C# with only value types will be a real drag and cause someone
to wonder what the benefit of using .NET is if you can't really use
.NET (and regular objects).
Philip, does MS has a clear strategy for how to develop apps using MDX
and keeping collection times to a minimum?
-c
note these are personal opinions, not official responses.
--
Phil Taylor
PM : DirectX SDK, Managed DirectX, Windows XP Inbox 3D screensavers, and a
few more bits and bobs.
http://msdn.microsoft.com/directx
This posting is provided "AS IS" with no warranties, and confers no rights.
"Chad Myers" <cmy...@N0.SP.4M.austin.rr.com> wrote in message
news:v5D_8.73441$88.12...@twister.austin.rr.com...
>
> "Tim Sweeney" <t...@epicgames.com> wrote in message
> news:#nRmyAOMCHA.1352@tkmsftngp11...
> > > > Does Microsoft take the possibility of using C# for game development
> > > > seriously? It seems like it could be considered either as a
gameplay
> > > > scripting language or as a full-blown development language once
> DirectX9
> > > > ships with full .NET support.
> > >
> > > Yes to both.
> > >
> > > We hope our wrapper layers' perf is such that folk would consider
using
> > > Managed DX for full blown development, not just tools and scripting.
> >
> > Hi Phil!
> >
> > The managed DirectX9 layer looks GREAT, by the way - very clean and
> > straightforward. It's clearly going to be one of the stronger aspects
of
> C#
> > and .NET programming.
have you followed the thread on the design changes for beta2?
we have further refined MDX to be more .NET like and take some of the "still
too COM-like" rough edges off. I think folk are going to be pleased.
which indicates MDX isnt the culprit with its careful type usage.
>
> Like he said, MDX makes a strong point to avoid heap-allocated objects
> (by sticking to structs and other value types, I assume) which avoids
> the need for GCing often.
yes.
>
> What you are experiencing is when you are using regular heap-allocated
> objects (your every-day normal objects). The GC worries about these.
> Supposedly, with MDX, since very few of the objects are allocated on
> the heap, the GC won't have to worry much about those and the collection
> period will only be a scant few milliseconds.
I suspect the activity Tim is seeing is normal GC'ing of objects who have
generationally aged and are due for collection. short-lifetimed objects are
typically the issue here. especially with high frequency of use/allocation.
>
> However, what I wonder about is if this will mean that all performance-
> minded MDX apps will also have to follow all these rules. Programming
> DirectX in C# with only value types will be a real drag and cause someone
> to wonder what the benefit of using .NET is if you can't really use
> .NET (and regular objects).
well, the easy answer is to avoid managed types, but that does reduce the
benefit. IMHO, the harder answer is, if perf is really an issue, then a
programmer just cant be so cavalier with object lifetimes and GC usage. its
my opinion this doesnt mean you must forsake managed types, just the "fire
and forget" memory management usage style with managed types with no care of
lifetime or frequency of use/allocation considerations. .
one style of usage that should work is, if one has the need for managed
types, just make sure their lifetime is the same as a level of the game, so
that you can defer dropping all refs till the next level load time, and then
you could then explicitly GC during the level load. thats frequent enough to
avoid memory issues, but not so frequent as to cause non-deterministic FPS
spikes.
yes thats a little more work, but to get more deterministic behavior
something needs to happen. no free lunches, one has to allow the GC its
timeslice, or defer it getting its timeslice to when it wont be noticed ( eg
level load time instead of frame time ) when using managed types. from what
I have observed there is no way around this without adopting a scheme such
as I mention. I might be underinformed here, and I will double-check that
monday when I am back on campus.
>
> Philip, does MS has a clear strategy for how to develop apps using MDX
> and keeping collection times to a minimum?
There isnt an official company strategy, nor one from the DX team...I will
think about this though, and start dialoging folk on what our guidance
should be.
Tim, please start a thread on the beta newsgroup about this, and I will get
some of the VS/CLR folk to reply with what the Everitt and Whidbey plans
are, and perhaps start a dialog about what possibilities there are for more
determistic GC control, if any.
If those kinds of control are not planned, then perhaps its time for a full
court press lobbying effort...
>
> -c
I just realized I forgot to say hi last time, :-).
--
Phil Taylor
PM : DirectX SDK, Managed DirectX, Windows XP Inbox 3D screensavers, and a
few more bits and bobs.
http://msdn.microsoft.com/directx
This posting is provided "AS IS" with no warranties, and confers no rights.
"Tim Sweeney" <t...@epicgames.com> wrote in message
news:#nRmyAOMCHA.1352@tkmsftngp11...
If only there were some way to exert high level control over the GC. Being
able to write part of the algorithm itself is probably too error prone, but
adjusting how frequently it kicks in, how long it acts, etc. would be handy.
It also shouldn't be too difficult to code, but the politics/bureacracy is
probably insurmountable. :-(
More practically, have you considered attempts to reduce your object
allocation? It sounds like you are creating the same types of objects over
and over. Aside from making the GC kick in, I assume this is expensive.
Keeping a static pool of recycled objects around, and then initializing rather
than constructing them should be faster and largely avoid the GC. You can
probably afford to grow the pool, and not even worry about shrinking it while
the action is going.
There'd be a little work in avoiding memory leaks, but that should be largely
avoided by making sure the recyclabe objects can't themselves contain links
to large objects, and probably no recursive links at all.
Actually, some sort of general tool based on a [Recyclable] attribute would
be cool.
-Jasper
The garbage collector runs in a separate thread. It should not pause a game
at
all. However, if a garbage collection only occurs every five to ten minutes
making
six thousand objects per second (!!!). Ten minutes at that rate is 3.6
million
objects (egad!). Two things I'm fairly certain I read on MSDN but I forget
where: 1) The *server* garbage collector version does pause (I think the
rationale is
that not having to work together with the main thread will make it more
efficient, whereas consumers will want a more consistently responsive
system),
and 2) All finalizers are called from the same thread, so if you use
finalizers that could be the bottleneck (maybe). Mr. Sweeney, I would be
curious to know what operating system you are using (.Net Server beta?).
:-) That or I'm entirely wrong and dillusional (always a possibility! ;-).
> (snip)
>
> There'd be a little work in avoiding memory leaks, but that should be
largely
> avoided by making sure the recyclabe objects can't themselves contain
links
> to large objects, and probably no recursive links at all.
>
> Actually, some sort of general tool based on a [Recyclable] attribute
would
> be cool.
IDisposable. :-) Perhaps with a hash table based on GetType()? ;-)
> -Jasper
Eh? It is highly unlikely that all other threads *won't* be suspended
during GC activity.
Jim S.
A few suggestions:
1) Run perfmon, look at the .NET memory counters, and see if you can
correlate something there with the behavior of your app. I'd look at the
managed heap sizes.
2) Make sure you're disposing of objects early
3) Use the allocation profiler to look at how your app is allocating
objects. Under "Tools and utilities" and the link below.
--
Visit the C# product team at http://www.gotdotnet.com/team/csharp
This posting is provided "AS IS" with no warranties, and confers no rights.
"Tim Sweeney" <t...@epicgames.com> wrote in message
news:#sNvbJJMCHA.1988@tkmsftngp08...
Have a nice day then :-)
Jim Bellinger
"Jim Sculley" <nic...@abraxis.com> wrote in message
news:3D3C1738...@abraxis.com...
"James F. Bellinger" <z...@neo.rr.com> wrote in message
news:TBW_8.145715$CJ2.17...@twister.neo.rr.com...
Either way though, I haven't experienced significant intermittent pauses in
Visual Studio .Net,
though it used to take a long time to load the help files for some reason
before I got a new
7200RPM hard drive. :-) :-)
One thing I would like to know, however, is if the 100 objects from every
frame are actually
used for any significant portion of time. If not, you should pool them. :-)
It seems strange
that it would only collect (most likely Generation 0) objects every 15
minutes, but if they are
really small it's a possibility I guess. Could you try calling GC.Collect(0)
every minute or
so and see what that does to performance?
Have a nice day :-)
Jim Bellinger
"James F. Bellinger" <z...@neo.rr.com> wrote in message
news:TBW_8.145715$CJ2.17...@twister.neo.rr.com...
Deterministic control over garbage collection would not solve this problem.
If Mr. Sweeney is allocating 100 objects per frame, at 60 frames per second,
and only getting a garbage collection every ten minutes (I assume these
objects
are being thrown away every frame, which seems likely as one cannot sanely
use that many for a long period of time), 3.6 million objects really
requires a
garbage collection. If a garbage collection only occured at level load time,
the user's system would be out of memory very, very soon. I mean, even
if these were only 16 byte objects, that's nearly 60 megabytes of memory
right there. :-) Garbage collection *must* happen during gameplay if
such an amount of allocated every frame, unless of course levels are
guaranteed to last only a couple minutes. Object pooling seems the only
logical solution to Mr. Sweeney's problem.
Except that he pointed out that the total time spent hung, presumably in
garbage collection, was small enough that it'd be acceptable -- provided
it didn't all happen at once. Wouldn't deterministic garbage allow you
to amortize the time spent?
I definitely agree that object pooling is the way to go, as simply avoiding
the need for allocation/collection would be best.
-Jasper
It's built 90%+ in unmanaged C++.
Peace,
Cameron Purdy
Tangosol, Inc.
.NET to J2EE porting service available
"James F. Bellinger" <z...@neo.rr.com> wrote in message
news:JSW_8.145772$CJ2.17...@twister.neo.rr.com...
>
Determinism isn't required. An incremental collector would do this
amortization for you. In the Java VM, you use the -Xincgc switch.
There is a small overall performance hit, but the collection pauses
become unnoticable.
Jim S.
I think we are talking about the same kind of thing. I didn't mean
deterministic as in explicit memory freeing, but rather in the looser sense
of being able to tweak the GC algorithm, like the -Xincgc switch you mention.
Sorry about the confusion.
-Jasper
Thanks :-) -Jim Bellinger
"Cameron Purdy" <cpu...@tangosol.com> wrote in message
news:OxF9aEoMCHA.1620@tkmsftngp10...
What puzzles me is why the uniprocessor collector doesn't operate in a
separate
thread. The documentation says that on a multiprocessor machine, the
workstation collector runs on one separate thread, and with the server GC on
a multiprocessor machine, a number of threads. It seems to me that even on
a uniprocessor system there would be some benefit.
I'd be curious to know the performance characteristics if Mr. Sweeney called
GC.Collect(0) every thousand frames or so (just to get rid of all the short
lifespan objects).
The IDE is a mix. There's a fair amount of C++, but modules like the
property grid are managed code.
--
Visit the C# product team at http://www.gotdotnet.com/team/csharp
This posting is provided "AS IS" with no warranties, and confers no rights.
"James F. Bellinger" <z...@neo.rr.com> wrote in message
news:YyA%8.155120$CJ2.18...@twister.neo.rr.com...
My source was "Eric Gunnerson [MS]".
Peace,
Cameron Purdy
Tangosol, Inc.
.NET to J2EE porting service available
"James F. Bellinger" <z...@neo.rr.com> wrote in message
news:YyA%8.155120$CJ2.18...@twister.neo.rr.com...
>