• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
MARS_999

Anyone having issues with Dual Core CPUs and timers?

24 posts in this topic

I have a dual core cpu and my timer works fine until I move around a bit and then it goes crazy? I not sure where to start with this. I am using the following functions QueryPerformanceCounter(&framedelay); QueryPerformanceFrequency(&tickspersecond); Thanks
0

Share this post


Link to post
Share on other sites
I believe it's because both cores return a different value for the timer.
0

Share this post


Link to post
Share on other sites
There are tones of posts about this ever since the AthlonX2 cores came out.

The problem is the two cores have seperate clocks, so using the high performance counters will cause errors, as each core
returns a slightly different value.

There are several fixes.
-Some people manage to get the patches from AMD and MS to work. (I didn't :( ) These are the new drivers for cool-and-quiet and a patch for QPC.
-You can force the thread that is runnning the timing code to run on only one core by setting the affinity of that thread to only the first CPU.
-You can get a program like WinlauncherXP, and use it to force the afinity for you(good for retail programs that have problems, like COD2).
0

Share this post


Link to post
Share on other sites
You can force the thread that is runnning the timing code to run on only one core by setting the affinity of that thread to only the first CPU.

This sounds good, but I have never done this before. So is there some function call for this? e.g. SetProcessorAffinity() GetProcessAfinity()?

thanks
0

Share this post


Link to post
Share on other sites
There's also SetProcessAffinity(), which locks the affinity for an entire process.

However, the right solution is to get the patches from MS and AMD to work. I had no problems with that, and I don't know anyone who did, so it's clearly possible.

QueryPerformanceCounter() is intended to be the reliable, bug-free, cheap counter you can use, now that RDTSC is discouraged. The continual bugs with that call (first the jump-ahead-4-seconds bug, then the jump-ahead-1.3-seconds bug, and now the dual-core bug) is doubly unfortunate.

0

Share this post


Link to post
Share on other sites
for a game use a different method of querying the number of ticks under windows
iirc something like either
timeGetTime()
getTickCount();

theres no need for such a high resolution timer (this is only needed if u wanna test a func etc + see how long it takes)
0

Share this post


Link to post
Share on other sites
When one runs into these sorts of problems, it can be most beneficial to check the Help and Support section of MS's site. Upon searching, I've come across the following two pages:

http://support.microsoft.com/kb/327809/en-us

http://support.microsoft.com/kb/909944/en-us

And yes, this is a well known issue.
0

Share this post


Link to post
Share on other sites
Well I tried the __int64 variable and still a no go. One of the MSDN posts said to use __int64...



__int64 tickspersecond;
__int64 currentticks;
__int64 framedelay;

void Timer::Init(float tfps)
{
targetfps = tfps;
QueryPerformanceCounter((LARGE_INTEGER *) &framedelay);
QueryPerformanceFrequency((LARGE_INTEGER *) &tickspersecond);
}

void Timer::SetSpeedFactor(void)
{
QueryPerformanceCounter((LARGE_INTEGER *) &currentticks);
//This frame's length out of desired length
//speedfactor = (float)(currentticks.QuadPart-framedelay.QuadPart)/((float)tickspersecond.QuadPart/targetfps);
speedfactor = float(currentticks - framedelay) / float(tickspersecond / targetfps);
fps = targetfps/speedfactor;
if(speedfactor <= 0)
speedfactor = 1;

framedelay = currentticks;
}




still no dice

[Edited by - MARS_999 on August 15, 2006 3:08:14 AM]
0

Share this post


Link to post
Share on other sites
LARGE_INTEGER is essentially just a wrapper around __int64, so swapping one for the other won't help at all. You should either install the patches or use SetThreadAffinityMask to force the timer thread onto one processor.

Personally, I use the SetThreadAffinityMask method, since I know that otherwise if I release an app using QPC(), someone will complain that it doesn't work and that it's "my fault" for not fixing it somehow.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
LARGE_INTEGER is essentially just a wrapper around __int64, so swapping one for the other won't help at all. You should either install the patches or use SetThreadAffinityMask to force the timer thread onto one processor.

Personally, I use the SetThreadAffinityMask method, since I know that otherwise if I release an app using QPC(), someone will complain that it doesn't work and that it's "my fault" for not fixing it somehow.


Thanks for the reply Evil Steve, so how does your code look for SetThreadAffinityMask then if you don't mind me asking... Thanks
0

Share this post


Link to post
Share on other sites
Quote:
Original post by MARS_999
Thanks for the reply Evil Steve, so how does your code look for SetThreadAffinityMask then if you don't mind me asking... Thanks
Just in my main thread:
SetThreadAffinityMask(GetCurrentThread(), 0x01);

I think anyway, I don't have my code with me.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603

However, the right solution is to get the patches from MS and AMD to work. I had no problems with that, and I don't know anyone who did, so it's clearly possible.



Actually, the right solution is to set the thread affinity. You cannot rely on your customers to be patched correctly.
Do not use the SetProcessAffinity unless you don't want your application taking advantage of the dualcore performance enhancements, just use SetThreadAffinityMask and make sure your counter runs on its own thread.
0

Share this post


Link to post
Share on other sites
Quote:
just use SetThreadAffinityMask and make sure your counter runs on its own thread.

huh, that sounds not exactly lightweight. So does your get_time() API send a message to the timer thread and wait for an answer?
0

Share this post


Link to post
Share on other sites
That's not what he meant - you don't have a thread that runs your timer and nothing else; you just run your timer in the same thread that needs being timed.

A better way to say it is that every thread that checks timings needs to maintain its own timer variables internally, and set its own processor affinity mask. If you're willing to do a little work, you can even check for multiple processors, and set up the affinities so that your threads are more evenly distributed across the available CPUs.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by bit64
Actually, the right solution is to set the thread affinity. You cannot rely on your customers to be patched correctly.

Sure you can, its done all the time. Pick any random game, and I'll bet they suggest updating your video card drivers if you experience problems.

CM
0

Share this post


Link to post
Share on other sites
Quote:
you just run your timer in the same thread that needs being timed.
A better way to say it is that every thread that checks timings needs to maintain its own timer variables internally, and set its own processor affinity mask.

Timer state in TLS? Interesting.
Doesn't sound too safe, though - if 2 threads (UI and main engine) have some timestamp they need to agree on, you are back to square 1.

Quote:
If you're willing to do a little work, you can even check for multiple processors, and set up the affinities so that your threads are more evenly distributed across the available CPUs.

hoo boy, sounds dangerous. You need to take HT into account, else your game will run like a dog when you farm out worker threads to every single virtual 'CPU'. You have therefore committed yourself to releasing patches for all future CPU changes (e.g. when AMD adds something like HT).

Also, if user is burning a CD while playing your game (now quite viable with dual core), you potentially mess that up for him. Probably better to let OS take care of scheduling!
0

Share this post


Link to post
Share on other sites
Perhaps I should be more clear. When I say that you should make sure that your timer calls are on their own thread, I mean that the differences between SetProcessAffinity and SetThreadAffinity are only remarkable if your application has more than one thread! Simple as that.

Calling SetProcessAffinity on a multithreaded application will kill any advantage you would have of running on a dual core CPU.


0

Share this post


Link to post
Share on other sites
Slight problem that on Windows XP x64 uses the server kernel, QueryPeformance* functions will use the time stamp counters (rdtsc). (At least it did at the time when it was in beta). Also, the HPT timers are relatively expensive to use (not that you have too much options). There is an excellent article on gameDev's (see resources) on timing in windows.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by zedzeek
for a game use a different method of querying the number of ticks under windows
iirc something like either
timeGetTime()
getTickCount();

theres no need for such a high resolution timer (this is only needed if u wanna test a func etc + see how long it takes)


Errrr, wrong. timeGetTime can be quite off. If you want decent animation you need very precise time. Not something 1-2ms off. Well, maybe you do, but not me.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Conner McCloud
Quote:
Original post by bit64
Actually, the right solution is to set the thread affinity. You cannot rely on your customers to be patched correctly.

Sure you can, its done all the time. Pick any random game, and I'll bet they suggest updating your video card drivers if you experience problems.

Going to have to disagree with you on this one. The nature of this glitch is such that it's often left unpatched as a means of gaining an unfair speed advantage in the game Planetside, to name an example. Sure, that's due to shoddy netcode in no small way, and isn't without it's detremints, and really isn't THAT much of a game breaker, but it's enough to severely piss off a large segment of their customer base - and not the ones who's own dumb fault it is, either.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by DaBookshah
Quote:
Original post by hplus0603
.....RDTSC is discouraged....


Why?


If I remember right because multicore cpus have different timers that may not be in sync (basically the main cause of the problems mentioned in this thread). Also if the cpu throttles speed(I think they are all capable of it now days), then you times no longer match reality. For instance SW:KtoR, would play at a different speed on my laptop if I unplugged the power (which throttle the cpu to 600 from 100 MHz) while playing. I think the only good use of rdtsc is to measure the number of cycles a piece of code uses. Assuming you set the affinity and took the minimum cycles of numerous test to help remove problems from windows changing the threads.

Also x64 installs (A least I think mine did) with /usepmtimer in the boot.ini so it's not supposed to use rdtsc for QPC. That option may have been enabled by a patch too (I didn't see it until my system was fully patched up).
0

Share this post


Link to post
Share on other sites
Now that's nice.. I read this thread yesterday and suddenly I realized why Neverwinter Nights didn't work correctly on my computer. It's patched up with all the latest patches and I thought I had the newest amd patched but after (re)installing the latest amd patches it worked great!
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0