Bind single-threaded apps to a single core

Started by
10 comments, last by Sik_the_hedgehog 12 years, 2 months ago
Hello guys, I'm working on an old game that needs to be ported to modern windows systems. The game is single-threaded, and one of the bugs they assigned to me is to bind the main thread to a fixed core on multi-core cpus. While this should be easy enough, I was wondering if there would really be a good reason for that, and how it may affect the performance and the os. Should I really do that?

Edit: As I said it's an old game, so extreme performance is not an issue at all. Cache misses due to core swapping are hardly a concern.
[ King_DuckZ out-- ]
Advertisement
I was wondering if there would really be a good reason[/quote]

Timing is the most common source of bugs when swapping cores. There could be others, more obscure ones.

Issues might also be related to third-party libraries or worse, the drivers.

Should I really do that?[/quote]

You could always fix the code.... Which isn't really viable since such bugs are hard to reproduce.

Or just make a batch file "start /affinity 1 foo.exe".

Timing is the most common source of bugs when swapping cores. There could be others, more obscure ones.
[/quote]
Indeed, I didn't think of QueryPerformanceCounter(). The timer implementation is using it, and being an old code for single core it's not even trying to make up for the possible discrepancies.


You could always fix the code.... Which isn't really viable since such bugs are hard to reproduce.
[/quote]
Also timing code isn't wrapped into only one or two classes... the original programmer had a vocation for copy & paste, so there's hundreds of direct calls with the subsequent transformation into milliseconds. Sometimes you even see the same comments over and over in the code.


Or just make a batch file "start /affinity 1 foo.exe".
[/quote]
Tbh I was rather thinking to use SetThreadAffinityMask(GetCurrentThread(), 1) in the WinMain. Are the two solutions equivalent or are there arguments in favour of one rather than the other?
[ King_DuckZ out-- ]
No, they do the same thing.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Great, thanks! :)
[ King_DuckZ out-- ]
Also timing code isn't wrapped into only one or two classes... the original programmer had a vocation for copy & paste, so there's hundreds of direct calls with the subsequent transformation into milliseconds.[/quote]

Then it's anyone's guess on why it works or not and what threads have to do with it.

Time will usually be read once per frame, then that value gets passed around. Reading time many times per frame is conceptually difficult, since simulation clock and wall clock aren't synchronized. For various reasons, different stages of frame may take different time, especially considering new hardware has different characteristics. While everything is faster, relative time per operations differs.

It's even worse if frame tick goes through several stages, perhaps advancing simulation five times. On faster hardware and due to QPC quirks, these stages could easily end up taking 0 time, causing all kinds of mess.

Fixing code for simple maintenance job likely isn't viable, but timing really is a mess.

Hopefully, floats aren't involved...
What's the preferred method of dealing with the "QPC on old dual core machines" problem? Do developers simply ignore the issue? I was one of the unlucky people to experience the bug and it was definitiely present in several big name titles I played.

Is it safe to conclude that QPC is fixed on modern (all quad core and above) platforms?

What's the preferred method of dealing with the "QPC on old dual core machines" problem? Do developers simply ignore the issue? I was one of the unlucky people to experience the bug and it was definitiely present in several big name titles I played.

Is it safe to conclude that QPC is fixed on modern (all quad core and above) platforms?


After spending a good week straight of scouring google, msdn, gamedev, stackoverflow, and pretty much anything else I could find about QPC, I'm pretty sure its fixed on any modern platform. From what I understand it was only a few isolated platforms, and there were bios/OS patches released for most of them. The general consensus was to just ignore the issue. Unfortunetly there is no single definitive article explaining it all in detail, and the MSDN docs are just terrible (which is surprising given it is such a key issue). I wish Microsoft would just list the platforms that had issues somewhere, it seemed to be far fewer than what the docs made it sound like. There's also an easy work-around for those systems that do have errors.

In a nut-shell, the problem is older systems didn't have the HPET and QPC would instead use the Time Stamp Counter (TSC) which of course wasn't sychronized between the cores. Turns our there is another timer on most systems called the PM timer, which is pretty much just the HPET but a little slower. Why Windows decided to use TSC over the PMTimer for QPC I'm not entirely sure, but its easy to force it (explained here: http://blogs.technet.com/b/perfguru/archive/2008/02/18/explanation-for-the-usepmtimer-switch-in-the-boot-ini.aspx).

Was there a system out there that had dual cores and didn't have the PMTimer either? I have no idea, nor did I see this possibility ever mentioned. In the end my conclusion was that the QPC issues are a thing of the past, and easy to rectify if in the rare chance that someone was still using one of the old dual core systems that hadn't updated their OS.
A bit late since I just see this thread.

Hello guys, I'm working on an old game that needs to be ported to modern windows systems. The game is single-threaded, and one of the bugs they assigned to me is to bind the main thread to a fixed core on multi-core cpus. While this should be easy enough, I was wondering if there would really be a good reason for that, and how it may affect the performance and the os. Should I really do that?

Timing issues as mentioned in this thread are one reason, another reason could be some potential race conditions that would never arise on a single core (since only one thread is running at a time) but could possibly become an issue on multiple cores (since multiple threads are running and accessing hardware resources at the same time).


Or just make a batch file "start /affinity 1 foo.exe".

Tbh I was rather thinking to use SetThreadAffinityMask(GetCurrentThread(), 1) in the WinMain. Are the two solutions equivalent or are there arguments in favour of one rather than the other?[/quote]
Well, your idea would work always even if the user runs the executable directly instead of using the batch file =P

Was there a system out there that had dual cores and didn't have the PMTimer either? I have no idea, nor did I see this possibility ever mentioned.

No idea, but there could have been systems where using the PM timer caused bugs though. Looking up, the PM timer seems to be related to power management, so maybe using the PM timer on those systems can actually mess up the ability to do proper power management? I can see why Microsoft would want to avoid that.
Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

[quote name='King_DuckZ' timestamp='1329408096' post='4913681']Hello guys, I'm working on an old game that needs to be ported to modern windows systems. The game is single-threaded, and one of the bugs they assigned to me is to bind the main thread to a fixed core on multi-core cpus. While this should be easy enough, I was wondering if there would really be a good reason for that, and how it may affect the performance and the os. Should I really do that?

Timing issues as mentioned in this thread are one reason, another reason could be some potential race conditions that would never arise on a single core (since only one thread is running at a time) but could possibly become an issue on multiple cores (since multiple threads are running and accessing hardware resources at the same time).
[/quote]
Care to expand on what race conditions could arise in a single threaded application running on a multi-core system?
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

This topic is closed to new replies.

Advertisement