Set processor affinity programmatically in a multi-core system

There are a few different ways to set processor affinity and Edmond Woychowsky shows you two programmatic ways he has used in his projects.

Early on in the history of the personal computer an author and technology prophet, Jerry Pournelle, authored a law that went like this, "One user, one CPU". At the time a statement like that was something akin to heresy. It was, after all, a time when dinosaurs ruled the computing world and personal computers were looked upon as little more than very expensive toys.

However, time passed and in subsequent years Pournelle's law came to be considered somewhat conservative. So much so, in fact, that he actually modified his law to "One user, at least one CPU", which is essentially where we are now. Unfortunately, for developers, Jerry Pournelle never actually said what to use the additional processing power for.

My own devices

As a developer left to my own devices the first use that I'd consider would be a multi-threaded application, but what if my goal was something that didn't readily lend itself to multi-threading or what if it was a prepackaged application?

Either of those scenarios would be an issue, fortunately there is a solution to both that dates back to the very-same days when personal computers were considered little more than very expensive toys. A point of interest to consider, is that, in those days, some of the high-end dinosaur computers actually had more than one CPU, what the system administers in those days would do with those machines is to treat them as multiple computers in a single box.

Alright, now that I know what I want to do, that only leaves the question of just how to accomplish the task. Fortunately there are both a programmatic solution for my own applications and a lazy approach for pre-written software. Being counted among the lazy, let's take a look at that approach first.

Manually setting processor affinity

Figure A shows soffice.exe task in the task manager which is the file for Open Office, the open source office application suite, along with the various options available. One of these options is Processor Affinity, which when clicked on displays the pop-up shown in Figure B that has a check box for each core. Processor affinity is set by checking one or the other check box. In cases where both are checked the operating system will attempt to balance the load between the cores.

Figure A

Vista task manager

Figure B

Processor affinity

Now the real fun begins, because as the administrator of my own little computer I have both the power and ability to check or un-check the boxes as I feel necessary. Or, as I say when I'm feeling a bit of megalomania, "Let it run on the second core today." The result of this mental aberration is displayed in Figure C.

Figure C

Open Office on the second core

Setting processor affinity in C#

Ah, here is where I can really let my megalomania run free, programmatically picking which core or cores my application will run on, now that's real power. Alright, I admit it, in my case it's more of a not completely locking-up the computer if things don't work-out the way I intended. Come to think of it; things not going as intended is a perfect demonstration of processor affinity. Nothing says whoops like a tight loop.

To work with processor affinity in the .NET environment it is necessary to use the System.Diagnostics namespace which contains Process class from which the GetCurrentProcess() method is used to obtain a new process and associate it with the current active process. Of course, if I was working with a multi-treaded application I'd be using a different method.

Once the process is obtained the ProcessorAffinity property can be used to either set or get the processor affinity. It is important to remember that the ProcessorAffinity property is a bit mask where each bit represents a single CPU, so a system with a dual core CPU the possible values are as shown in Table A.

Table A

Value

Description

1

Use the first core

2

Use the second core

3

Use both the first and second cores

The code required to demonstrate processor affinity is surprisingly simple as Listing A illustrates. The result of the code is shown in Figures D and E.

Figure D

Demonstration running

Figure E

Vista task manager

Conclusion

Developers being what they are, when given more of anything will undoubtedly find some way to use it. Don't believe me? Leaving an unattended pizza anywhere near a group of developers will prove me right. Seriously though, I hope that this example of what to do with the bounty of processing that Jerry Pournelle foresaw is of some use, especially for those occasions when, for one reason of another, multi-threading is out of the question.

How about a simple C or Perl routine that can get and set the affinity for any pid? By name? by Tid? By user?...
I can think of a few uses for cmd line control -- like setting all my "background" system processes to run on cpu-0, all of my direct-service system or background (mouse control, security monitor, DNS, etc) processes (ones that clients have to wait on for services) on 0-or-1, Then isolate a game on 2 & 3. Since 2+3 share a cache on Intel -- with an 8MB cache, and 2+3 dedicated to game -- no matter what thread is running on which processor, more chance of sharing cached code.

I tend to *not* choose processor affinity when I write multithreaded code, since it is a crapshoot anyways if I am making the right decision. What circumstances do you see this being used in, and how do you reliably determine the best CPU to grab on to?
Thanks!
J.Ja