[.net] Timing method jumping around like an EKG

Started by
7 comments, last by Roof Top Pew Wee 18 years, 8 months ago
At first the answer to this problem seems like it is obviously something related to the garbage collector, but I honestly don't think so. I'm running a game that I wrote in MDX and C#. However, I have been noticing small "jumps" in my movement. As the intensity of the graphics on screen increases (more objects with larger textures) this jump becomes more pronounced. So, I thought that my issue was overallocation of memory causing the GC to kick in and temporarily freeze my program. However, running the CLR Profiler shows that the GC is barely doing anything. Sure, the CLR Profiler slows down my program causing fewer frames to be rendered and less memory to be allocated in general, but I think it averaged something like 40 MB total allocation in 12 minutes of runtime. Framerate dropped around 50-25% of regular. That's hardly enough to push the GC. It gets weirder. So I decided to keep a history of my frame times and printed them out on a the screen using a scrolling list as my game was running. Even though the list was scrolling quickly, I noticed a pattern. I put in the option to freeze the scrolling of times and noticed something very interesting. All of the frames would be normal .. . taking around .022 seconds each , then suddenly one frame would take nearly .1 second, then the following 3 - 5 frames would take much less time, then the frames would resume to normal time. The sudden peak and drop reminded me of an EKG. Then the really weird thing. I decided to time the amount of time between these spikes. . and I found that it was almost exactly 1 second between each spike. Within .02 seconds each time, and I think this varying has to do with the frames not quite matching up with the second exactly. Still unsure what was causing this spike at almost exactly every 1 second (and it was consistent - never skipping a second after initialization), I started to time individual methods by querying the performance counter before and after methods, and trying to narrow it down to which part of my code was causing the problems. I printed out the times to a .txt file, only storing the times during the frames that peaked in time. The really weird thing is that when I'd add up the time spent in the individual sections of my loop, they wouldn't add up to the amount of time spent in the loop. Sometimes it'd be twice as long, sometimes nearly the same amount of time .. .which is leading me to believe that it's my timing method that's causing the problem. Also, if I take the seconds involved in the spike and drop, add them up, the amount of time spent in all of the faster and slower frames equals the amount of time that would have passed if the frames were normal. It seems as if the timer is jumping ahead, then slowing down. However, I'm pretty sure that I'm doing timing right:


[ System.Runtime.InteropServices.DllImport("Kernel32.dll")]
static extern bool QueryPerformanceCounter(out long perfcount);

[ System.Runtime.InteropServices.DllImport("Kernel32.dll")]
static extern bool QueryPerformanceFrequency(out long freq);


public static void Update()
{
	EndTick = CurrentTick;
	QueryPerformanceCounter(out CurrentTick);

	TickDifference = CurrentTick - EndTick;
	SecondDifference = (float)(TickDifference/(double)TickFrequency);
}

And of course, I base my movement off of SecondDifference. I wrote a rather long post just to show that I've tried a lot of things to solve this problem. I'm pretty much fresh out of ideas. Has anyone had this problem with timing before? If so, how can I get around it? And also, on a side note, are there other timing methods I should look at? It really seems to be that the timing methods are causing these problems according to my tests. --Vic--
Advertisement
I notice these hickups as well in every dx sdk mdx sample, BUT only in windowed mode, try going fullscreen and see how things turn out. (Not a solution but hey, at least it's something)
Yeah, exactly. This all occurs only in windowed mode (I guess I should have mentioned that in my first post) and switching to fullscreen fixes it. No workarounds?

--Vic--
Does the same thing happen with the non-managed samples?

Anyway, I long while back I was having a similar problem, but I'm not sure if it was exactly the same one or not, and may only be specific to how I handled timing. My timing method basically worked this:

The timing code keeps track of how many logic updates it has performed so far, and also how many updates it thinks it ought to have performed. If for any reason the number of updates it has performed falls behind the number it thinks should have been performed (which I found happened about once a second, I'm assuming do to accumulating timer innacuracies), the timing code would perform as many additional updates as were necessary to catch up.

The problem here was that, if it fell behind, then the system would perform two whole updates, causing a small but very noticeable jump in the action. My solution, which fixed the problem perfectly in my case, was to not perform an extra "catch-up" update immediately, but to reduce the time between updates for about a second so that within a second the system had sufficiently caught up to where it thought it should be while not causing any sudden jumps.

Again, I'm have no idea if your timing system works anything like this, but if it does then my solution is probably worth a try.

- Fyzz
As stated, if it's in the dx sdk mdx samples in windowed but not fullscreen mode then our own timing functions realy shouldn't matter now :p

Edit:

Just to be sure, seeing as there's a new sdk out, now, the mdx samples doesn't hickup. Sure, this might just be a coincidence and i'll get the hickups later on, seeing as i'd guess it's "windows" related because of the windowed occurances and none in fullscreen.

But as it is now, i'm not experiencing them.
I'm using April, so I'll upgrade and see if it improves.

--Vic--
<sigh> Still having the problems with the latest DX (Aug 05). I've ran the DX samples for both August and April 05 and found the same skipping occurs there as well in windowed mode. Has anyone else seen this? Is this a common problem for windowed DX apps? I don't see how this could go unnoticed by MS if it is something common.

--Vic--
http://www.gpwiki.org/index.php/VB:Timers
I've implemented the timeGetTime discussed in the gpwiki article, and still no success. I get the exact same spike in my frame time using that timing method once per second. Any other thoughts? How is everyone else doing timing in their C# games?

--Vic--

This topic is closed to new replies.

Advertisement