/* attempt to deal with prototype, bootstrap, jquery conflicts */ /* for dropdown menus */

\$8

### Image of the Day Submit

IOTD | Top Screenshots

## Anyone having issues with Dual Core CPUs and timers?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

24 replies to this topic

### #1MARS_999  Members

Posted 14 August 2006 - 02:26 PM

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

### #2dublindan  Members

Posted 14 August 2006 - 02:29 PM

I believe it's because both cores return a different value for the timer.

### #3KulSeran  Members

Posted 14 August 2006 - 02:34 PM

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).

### #4MARS_999  Members

Posted 14 August 2006 - 02:43 PM

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

### #5okonomiyaki  Members

Posted 14 August 2006 - 03:40 PM

I've never used it, but I've seen it before.

### #6hplus0603  Moderators

Posted 14 August 2006 - 03:48 PM

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.

### #7zedzeek  Members

Posted 14 August 2006 - 04:40 PM

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)

### #8Anonymous Poster_Anonymous Poster_*  Guests

Posted 14 August 2006 - 05:23 PM

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.

### #9MARS_999  Members

Posted 14 August 2006 - 06:08 PM

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]

### #10Evil Steve  Members

Posted 14 August 2006 - 09:47 PM

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.

### #11MARS_999  Members

Posted 14 August 2006 - 09:52 PM

Quote:
 Original post by Evil SteveLARGE_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.

### #12Evil Steve  Members

Posted 14 August 2006 - 10:02 PM

Quote:

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

### #13bit64  Members

Posted 28 August 2006 - 03:16 AM

Quote:
 Original post by hplus0603However, 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.

### #14Jan Wassenberg  Members

Posted 28 August 2006 - 08:42 AM

Quote:

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

### #15ApochPiQ  Moderators

Posted 28 August 2006 - 09:01 AM

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.
Wielder of the Sacred Wands

### #16Conner McCloud  Members

Posted 28 August 2006 - 09:06 AM

Quote:
 Original post by bit64Actually, 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

### #17Jan Wassenberg  Members

Posted 28 August 2006 - 09:52 PM

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!

### #18bit64  Members

Posted 30 August 2006 - 12:10 PM

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.

### #19tompp  Members

Posted 30 August 2006 - 12:19 PM

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.

### #20MARS_999  Members

Posted 30 August 2006 - 03:18 PM

I am thinking that the use for HP timers would be needed for acurate physics?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.