Posted By
indi on 2006-01-16 07:26:16
| Yape
Hiya,
Just noticed this. It looks like your using the CPU timers to calculate framerate etc... Due to the new "dual core" CPU's, you also have to do this at the start.
HANDLE hThreadHandle = GetCurrentThread(); SetThreadAffinityMask( hThreadHandle, 1 ); // run on CPU 0 only!!
The timers on each core of the CPU aren't always in sync. This means that as the application multitasks, you can end up running of differnet cores, and as a result, the application "stutters" a lot. If you add in the 2 lines above, you will only run on CPU 0, which means you end up using the same timer, and it smooths out again.
You can do this via the task manager, but its a pain having to do it each time.
|
|
Posted By
Gaia on 2006-01-16 07:47:45
| Re: Yape
Hey Mike, thanks for the info. You know I still have an "old" 2.8 GHz (non-hyperthreading) Northwood core Pentium Nice beast you have I see....
|
|
Posted By
indi on 2006-01-16 07:55:25
| Re: Yape
hehehe... yeah, my work PC is a dual core 4.4Ghz machine, 2Gig ram and a 7800GTX card.
lovely!
I managed to get a 4.2Ghz dualcore chip for home too... It really does help smooth windows out... although its a sad state of affairs that you need this power to "smooth" operations in windows.
|
|
Posted By
Crown on 2006-01-16 10:29:03
| Re: Yape
This is only an issue if you really explicitely use the CPU timers, with direct assembly commands. I'd imagine that Gaia isn't doing that, so it could be easily something else.
I just checked on a dual core 64bit XP and couldn't see any serious jerking, just the one due to the monitor frequency (50 vs 60Hz), but that goes away as well if you have Vblank speed....
Gaia what do you use for timing?
|
|
Posted By
Crown on 2006-01-16 10:41:23
| Re: Yape
Mike, do you see the same issue with Vice as well? (just use the 64 emulator)
You can use the -singlecpu commandline parameter to force Vice to run on a single cpu on multi core systems (Its been there for ages, not that anybody really needed or used it)...
Let me know, if Vice has the same issue as well, on your setup or not.... (There has been some reports similar, but we couldn't track it down yet, and those were on single cpu systems.)
|
|
Posted By
Gaia on 2006-01-16 10:43:23
| Re: Yape
Crown is right, I am NOT using the 'rdtsc' instruction for timing, but a simple combo of QueryPerformanceCounter and Sleep (and also setting the timer resolution to 1 ms with timeBeginPeriod(1) in the beginning to be sure).
Jerkiness could also be caused by several high priority cpu-hogging tasks running. Make sure you're not compiling 3D Lemmings in the background ;-)
|
|
Posted By
Crown on 2006-01-16 11:22:08
| Re: Yape
I assumed you are using QueryPerformanceCounter which does not equals to the rdtsc instruction (in some cases it might, but the OS knows whether that is safe or not, and doesn't select it as a source on multicore systems where it is not safe). (Also it is not guaranteed that this is available at all, but I haven't seen a case when it wasn't, but in that case you can fall back to a millisecond timer)
It still could be the reason for jerkiness on Mike's computer, as the frequency of the QueryPerformanceCounter is not fixed, it can be different on any computers. the frequency might be a very large number, which can cause calculation overflows. You basically would need to do 128bit calculations, or need to scale the values to prevent overflows, this is what we do in Vice.
|
|
Posted By
Gaia on 2006-01-16 11:28:31
| Re: Yape
I forgot to mention that the counter is queried first with QueryPerformanceFrequency. By the way: is LARGE_INTEGER 128 or 64 bit on Win64?
I seem to recall a bug with the high resolution windows timers where they on certain motherboards simply leap ahead with no apparent reason... MS has a knowledge base article about that. I could never be bothered to deal with that though. It could be another reason... I still have a small proggy that checks for leaps with the timers so that could possibly be run on Mike's machine maybe?
|
|
Posted By
SVS on 2006-01-16 11:34:18
| Re: Yape
Mike: just unplug your freezer! (this is a citation of famous Jodrell Banks discovery of Quasars, do you know it?)
|
|
Posted By
Crown on 2006-01-16 11:40:13
| Re: Yape
LARGE_INTEGER is 64bit on Win64 as well... I wrote 128bit precision for the calculation, because you need to multiply in there, and that can overflow the 64bit range.
|
|
Posted By
indi on 2006-01-16 13:32:41
| Re: Yape
QueryPerformanceCounter uses the CPU timers. I was involved with Microsoft and the latest DirectX SDK and discussed this issue with them. They knew it was comming up and have placed a white paper about it somewhere.
But basically, the performance counters use the cpu counters. And yes, they "now" recommend that for now you set the CPU affinity if you use these functions.
If you get the window ms timer, then this isn't affected.
If you download the new December SDK you can search for "QueryPerformanceCounter" and it will find "Game Timing and Multicore Processors". Have a read of that, it goes in depth with it.... but comes to the same conclusion.
|
|
Posted By
indi on 2006-01-16 13:38:20
| Re: Yape
I'll have to try VICE at work. QueryPerformanceCounter also depends on motherboard resources. If its got a timer, it uses can use that as a prefrence. The machine at work obviously doesn't, but mine here seems to as neither YAPE or VICE glitch.
I'll try tomorrow....
|
|
Posted By
Crown on 2006-01-16 16:11:12
| Re: Yape
Just looked at it http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Game_Timing_and_Multicore_Processors.asp
So it says, due to 'bugs in the BIOS or motherboard drivers'. Well for this reason I wouldn't want to sacrifice multiCPU performance, just because a couple of manufacturers can't write proper drivers. They shouldn't get the WHQL logo on the first place, and Microsoft should put them on a blacklist as they are doing with printer drivers.
To accomodate the unlucky ones, who have such motherboards, the command line option should be more than enough to set the affinity, but it definitely should not be the default behaviour for applications. I'm quite surprised that Microsoft is actually recommending this. Instead of addressing the problem of improperly written core drivers, they basically create a new set of issues with a wrong recommendation.
What is the motherboard you have these issues on? Just so I can avoid it in my next purchase
|
|
Posted By
Crown on 2006-01-16 16:40:48
| Re: Yape
Actually setting the thread affinity doesn't solve the problem for all situations. We had some reports where these jerking problem came up a single CPU laptop. Now I assume, the problem there was that again a faulty BIOS selected the CPU timer as the source for the performance counter, it just forget, that the power management functions of the Laptop might change the frequency of the CPU, and apparently it did. Setting the thread affinity can't solve these cases, only having a secondary timer source could in this case.
So due to these issues should we abandon using the Performance counter, or should the people who made the bugs in the BIOSes should fix it?
|
|
Posted By
indi on 2006-01-16 17:12:15
| Re: Yape
No, as long as you refresh the range of the counters every (say) 100 frames or so, you should be fine.
Currently theres nothing much better than the Performace counters.....
As to the "bugs". Yeah, I have no doubt that there are. But that doesn't solve the problem! The fact that their there, and in so many motherboards, means you just have to deal with it.
Its an Asus SLI Deluxe....something.. Quite an expensive (and good) board.
Also so many things "pass" WHQL and still screw apps its unbelieveable... but I guess it can't catch everything...
|
|
Posted By
indi on 2006-01-17 06:21:52
| Re: Yape
VICE seems fine here.... Perhaps its already forcing each emulated CPU onto its own thread....?
Or it could be auto correcting already....
|
|
Posted By
Crown on 2006-01-17 07:45:19
| Re: Yape
Asus used to be good, and probably still is.
Vice doesn't force any threads to a specific CPU, unless you specified the -singlecpu commandline, or have the accompaining resource set in the .ini file. You can check on the Task manager performance screen, if both CPU are used or not, its visible.
In the Vice log there is a line 'Refresh rate:' followed by a bunch of numbers. The first number (in hex), is the frequency of the Performance counter, how much is that on your machine?
|
|
Posted By
indi on 2006-01-17 08:33:07
| Re: Yape
Refresh rate: 1079E446 / 4605635.50 = 60.019
|
|
Posted By
Gaia on 2006-01-17 09:33:59
| Re: Yape
That does not look like it'd overflow 64 bit... Mike, could you check Yape as well? There should be something like '50 Hz timer frequency' in the log window, followed by a decimal number (this should be in line with what VICE reports, but anyway). Cheers.
|
|
Posted By
indi on 2006-01-17 10:15:32
| Re: Yape
Its usually nothing to do with overflowing... its due to the fact that the "timer" differences can go negative... for example...Heres a few "ticks", the CPU you might run on, and the counter values you might get back...
Tick CPU Counter returned -------------------------------------------- 1 CPU 0 50 2 CPU 0 100 3 CPU 0 150 4 CPU 0 200 5 CPU 1 50 6 CPU 0 300 7 CPU 0 350 8 CPU 0 400 9 CPU 1 490 10 CPU 0 500
and so on... The problem is "normal" timing code doesn't take negative or very large values into account. And even if you do, you have no way of knowing how much time has "actually" passed.
Lets say you get counters 100,150,50....
Now, you can "guess" that you've swapped CPU, but that doesn't tell you how much time has elapsed since the last "tick" so you have to "flip" now. But that might be either to fast, or to slow and this is what results in the "judder" or even "freeze" - particually on negative values.
Also, time frequancy may change too... so you have to get that everynow and then to make sure you've delt with power management.
---------------------------------------------------- Yape reports this.....
High resolution timer frequency: -2083577296 Current monitor refresh rate: 60 Hz
|
|
Posted By
indi on 2006-01-17 10:16:16
| Re: Yape
Damn....forgot the /pre.... bugger.
Why's there no EDIT here!!
|
|
Posted By
Gaia on 2006-01-17 11:16:19
| Re: Yape
Yikes, -2083577296 sounds like a real bugger.... It's not supposed to be negative. I'll have to review the code I guess Yet it's only the logging part that apparently has a bug with this. For the rest it's just some divisions and additions. Although if the counter frequency is really that large it may overflow.
As for the EDIT: some people has that ;-)
|
|
Posted By
Crown on 2006-01-17 11:51:39
| Re: Yape
On mine Vice reports 14DC9380, while Yape -1494967296, but Yape works fine here.
Note that the freq on this machine is higher than the one on Mike's. Its drop dead 350Mhz, while the one on Mike's machine was ~276Mhz. I have no idea how that translate to CPU frequency tough, this one is a dual 2.8Ghz core.
The negative values are definitely completely off for sure.
On the other hand I just noticed an other 'bug' in Yape. If you have Video display emulation turned on, than the drop shadows of the Windows menus will be completely black instead of being transluent....
|
|
Posted By
Gaia on 2006-01-17 11:59:40
| Re: Yape
Cheers, Crown, for the values. Well, the counter frequency's QuadPart member is logged with a %d formatting character and a cast to 'long' within Yape. Actually, this structure member is 64 bit so who knows what happens... but this small glitch in the logger does not explain why Mike is experiencing that jerkiness.
As for the drop shadow: I seem to recall this but I use XP with the classic UI and no shadows VDU emulation is using overlays, I'll see if I can do sth about this (actually it 'should' work without any extra effort, shouldn't it?).
|
|
Posted By
Crown on 2006-01-17 12:11:03
| Re: Yape
Ok, I just looked at my source, what Vice reports is an already scaled down version of the Freq, if needed... I assume this is the case here!!
Check in win32/vsyncarch.c vsyncarch_init function. I basically scale the freq down to a level to prevent overflows... Probably that's what is missing in your code, and has been triggered on Mike's machine...
So yes the negative values are the actual freq ones, 2.8Ghz on mine, and 2.2Ghz on Mike's, this is probably halved by the the OS to fit into 64bit....
|
|
Posted By
Gaia on 2006-01-17 12:18:58
| Re: Yape
I am just looking at the code... it's rather clear. (Just for the record: my other desktop PC here reports 3 MHz Such a difference...) Any idea why the problem is triggered on Mike's PC only?
|
|
Posted By
indi on 2006-01-17 12:47:34
| Re: Yape
I really wouldn't fixate on the size of the value. It fits inside a LARGE_INTEGER as it was supposed to!
The problems as I said, are usually on the values you get back. Normally you store the last counter, then later get the current one and see how much time has passed.
But if the current one is LESS than the last one...or larger by more than you expected.... then you get you stutter. This is there these machines have problems!
|
|
Posted By
Crown on 2006-01-17 13:28:56
| Re: Yape
We had similar symptoms like this when we first encountered this issue, when the first 3Ghz CPUs came out, and had an other one later with a 2.2 Ghz one just like its happening here. My first fix was working on the 3Ghz one, but not on the 2.2Ghz one...
I would recommend, to do some debug logging in your sync code, that's the only way to actually confirm any of these theories, record all timestamps, and from that you should go through the calculations where the timestamps are used, and you might see what's going on....
|
|
Posted By
indi on 2006-01-17 15:30:24
| Re: Yape
I had a similar problem when I was doing mobile games, timers would go backwards as they sync up to remote clocks on transmitters. Its the same thing. And after talking to Microsoft about it too, they have the same opinion I have on it.
So... you can either "compinsate" which isn't very good... or lock it to one CPU. Everyone agrees its a bug in the BIOS, but that doesn't help. Its out there, so you have to deal with it.
|
|
Posted By
Gaia on 2006-01-17 18:20:15
| Re: Yape
Mike: could you grab this and see if your problem is sorted out?
|
|
Posted By
indi on 2006-01-18 09:24:46
| Re: Yape
Sorry no...still the same. I still have to go to the task manager and manually set the affinity.
|
|
Posted By
Gaia on 2006-01-18 10:06:40
| Re: Yape
Uhm, I haven't dealt with *that* (after all, VICE seemed to work fine, too) I did however make a similar recalibration of the timer values as what Tibor has mentioned. Could you tell me those values from the log window as last time? There's now a second value, that should be smaller on your machine.
|
|
Posted By
indi on 2006-01-18 11:24:14
| Re: Yape
Log... Perhaps Vice detects the 2 CPU's and forces itself onto one... or did I say that already
Log started. OS major version : 5 OS minor version : 1 OS build version : 2600 Window class created Current directory is: D:downloadsEmulatorsyape_timer_test Machine objects created. DDraw and GDI palettes created. Setting timer resolution to : 1 ms High resolution timer frequency: -208357729664 Rebased timer frequency: 6910593764 Current monitor refresh rate: 60 Hz Settings loaded successfully. Starting emulation.
|
|
Posted By
Crown on 2006-01-18 12:36:22
| Re: Yape
The default multiprocessor handling in Vice is that it sets the affinity to the system affinity, which in your case should be 2 CPUs. If you specify -singlecpu then it will set the affinity to the first CPU speficied by the system affinity.
So unless the system affinity is reported incorrectly on your system, Vice should run on both CPU, and if the QueryPerfomanceCounter on your system is not CPU thread safe, than it should exhibit the same jerking issues... Can you actually check whether Vice is running on both CPU?
The whole affinity setting code is in /arch/win32/ui-resources.c set_single_cpu function.
|
|
Posted By
Crown on 2006-01-18 13:07:17
| Re: Yape
Bummer I keep forgetting about these stupid unix style commandline parameters: +singlecpu turns on singlecpu mode -singlecpu enables multicore mode (default)
If you turn on Warp mode then in single cpu mode one of the CPU will max out at 100% while in multicore mode, both CPU usage is beetween 40-70%.... So it sort of easy to see in whether both CPU is in use or only one....
|
|
Posted By
indi on 2006-01-18 14:52:54
| Re: Yape
The AMD dual core chips aren't like 2 seprate CPU's, the command stream appears to be spread over both CPU's. That is you dont get one full and one empty... both appear around 50%...give or take...
|
|
Posted By
Crown on 2006-01-18 17:56:26
| Re: Yape
I'm not quite sure I get exactly what you mean, but any singlethreaded application on a multicore or multi CPU environment would be spread beetween the two CPU as you say around 50%, depending how the context switching comes out, if the affinity is set to both CPU, and this is done by the OS. If you set the affinity of the thread to one CPU, than it can only run on one CPU and naturally can max that CPU out to 100%. I don't see why AMD would differ here.
|
|
Posted By
indi on 2006-01-19 03:15:04
| Re: Yape
Well, if I have a single application thats running solid (say a tool of somekkind) that doesnt have a sleep, but is processing its data for around 1min without interruption, you'd expect one of the CPU's to be at 100% while the other would hover around 10-20 for the rest of the tasks in the system.
However, the AMD doesnt do that. Both CPU's get almost equal workload. Im not sure on the specifics, but its "not" just like a 2 CPU machine.... something else is going on with the instruction stream....
|
|
Posted By
indi on 2006-01-20 04:46:33
| Re: Yape
Thats better, nice and smooth again!!
Of course.... you could always put the Diskdrive on another thread and make use of that other processor!!
|
|