BrianPeek.com

A Compendium of Random Uselessness
in Search

XNA Timing Bug

Update - 12/24/07: This issue has been fixed in XNA Game Studio 2.0.  Woo hoo!

While working on my game for Maker Faire (which you'll be able to download in about a month), I came across a timing bug on the Xbox 360 using XNA.  For an application that requires very accurate timing (millisecond precision), one can use the StopWatch object in .NET 2.0.  This was working quite well in my PC build, but on the Xbox 360 build, I would notice that time would drift with no explanation.  After digging around for a couple days and writing a simple sample to prove the point, I determined that the time value returned by the StopWatch object would drift by about 150ms/minute, which is considerable when precision within a few milliseconds is required (and considerable when it should be accurate to begin with).

I eventually found a workaround:  DateTime.UtcNow.Ticks is perfectly accurate on both platforms.  So a quick rewrite to use this property in all locations requiring accurate timing fixed everything quite nicely.

The item is bugged and confirmed as such by the XNA folks, sample code is sent to the XNA team and it will hopefully be fixed in a future version.  But, for now, if you're looking for accurate timing on the 360, DateTime.UtcNow.Ticks is your friend.

Update: After Chad's comment on CodeBetter.com, just wanted to clarify a few things...

  1. DateTime.UtcNow.Ticks may in fact not be precise on any given platform.  As stated below, sitting in a tight loop may not see the Ticks value increase for several milliseconds.
  2. StopWatch internally actually uses DateTime.UtcNow.Ticks if the QueryPerformanceCounter doesn't give back the results the StopWatch wants (precision information).  On the 360 side of things, QPC does return the valid information to the StopWatch so QPC is what gets used.
  3. The issue above is not one of precision, it's one of accuracy.  The length of a millisecond on the 360 according to StopWatch/QPC is just plain wrong.  Updates to the StopWatch value are certainly quite fast (millisecond precision) yet over time, comparing the time to "wall time" or DateTime.UtcNow.Ticks shows that the StopWatch runs slower than real-world time by about 150ms per minute.  It never catches up and in fact, just drifts further and further behind.  After about 10 minutes, StopWatch is one second in the past.  But again, only on the 360.  On the tested PCs, there was a drift of only 2 or 3 milliseconds in that same ten minute timeframe.
Published May 30 2007, 02:48 AM by Brian Peek
Filed under: ,

Comments

No Comments

Leave a Comment

(required)  
(optional)
(required)  
Add

About Brian Peek

Brian is a Microsoft C# MVP who has been actively developing in .NET since its early betas in 2000, and who has been developing solutions using Microsoft technologies and platforms for even longer. Along with .NET, Brian is particularly skilled in the languages of C, C++ and assembly language for a variety of CPUs. He is also well-versed in a wide variety of technologies including web development, document imaging, GIS, graphics, game development, and hardware interfacing. Brian has a strong background in developing applications for the health-care industry, as well as developing solutions for portable devices, such as tablet PCs and PDAs. Additionally, Brian has co-authored the book "Debugging ASP.NET" published by New Riders, and is currently co-authoring a book titled "Coding4Fun: 10 .NET Programming Projects for Wiimote, YouTube, World of Warcraft, and More" to be published by O'Reilly in November 2008. Brian is also an author for MSDN's Coding4Fun website.

Copyright (C) 2008 Brian Peek
Powered by Community Server (Commercial Edition), by Telligent Systems