Jump to content

  • Log In with Google      Sign In   
  • Create Account


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.

  • You cannot reply to this topic
24 replies to this topic

#1 MARS_999   Members   -  Reputation: 1151

Like
0Likes
Like

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

Sponsor:

#2 dublindan   Members   -  Reputation: 448

Like
0Likes
Like

Posted 14 August 2006 - 02:29 PM

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

#3 KulSeran   Members   -  Reputation: 1934

Like
0Likes
Like

Posted 14 August 2006 - 02:34 PM

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


#4 MARS_999   Members   -  Reputation: 1151

Like
0Likes
Like

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

#5 okonomiyaki   Members   -  Reputation: 548

Like
0Likes
Like

Posted 14 August 2006 - 03:40 PM

Check out SetThreadAffinityMask.

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

#6 hplus0603   Moderators   -  Reputation: 4527

Like
0Likes
Like

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.



#7 zedzeek   Members   -  Reputation: 528

Like
0Likes
Like

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)

#8 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

0Likes

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.


#9 MARS_999   Members   -  Reputation: 1151

Like
0Likes
Like

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]

#10 Evil Steve   Members   -  Reputation: 1946

Like
0Likes
Like

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.

#11 MARS_999   Members   -  Reputation: 1151

Like
0Likes
Like

Posted 14 August 2006 - 09:52 PM

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

#12 Evil Steve   Members   -  Reputation: 1946

Like
0Likes
Like

Posted 14 August 2006 - 10:02 PM

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.

#13 bit64   Members   -  Reputation: 218

Like
0Likes
Like

Posted 28 August 2006 - 03:16 AM

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.

#14 Jan Wassenberg   Members   -  Reputation: 982

Like
0Likes
Like

Posted 28 August 2006 - 08:42 AM

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?

#15 ApochPiQ   Moderators   -  Reputation: 12399

Like
0Likes
Like

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.

#16 Conner McCloud   Members   -  Reputation: 1135

Like
0Likes
Like

Posted 28 August 2006 - 09:06 AM

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

#17 Jan Wassenberg   Members   -  Reputation: 982

Like
0Likes
Like

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!

#18 bit64   Members   -  Reputation: 218

Like
0Likes
Like

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.




#19 tompp   Members   -  Reputation: 126

Like
0Likes
Like

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.

#20 MARS_999   Members   -  Reputation: 1151

Like
0Likes
Like

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.



PARTNERS