Page 1 of 1

CPU Affinity on multi-processor and hyperthreading PC

Posted: Thu Jul 28, 2005 10:35 pm
by Max.
Very simple, so not worth a Tip & Trick, but still very interesting IMO.

Code: Select all

;Sets the CPU affinity, i.e. which CPU(s) are working on a process.
;To verify it, open the Task Manager, right click a process and check for the affinity there
;The affinity is a binary mask, so 1=CPU0,2=CPU1,4=CPU2,8=CPU3 and so on.
;Add the values for the CPUs you want to use to get the mask, like
;9=8+1=CPU3+CPU0
;Max. - forum.purebasic.com - 07/28/2005

#PROCESS_ALL_ACCESS=$1F0FFF 

lpProcessAffinityMask.l
lpSystemAffinityMask.l

Program.s = "Window Title of the Application"
CustomAffinity = 1 ;run on CPU0.


hWnd = FindWindow_ (0,Program)
result = GetWindowThreadProcessId_(hWnd,@pid)
pHandle = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pid)

;Result = GetProcessAffinityMask_(pHandle,@lpProcessAffinityMask,@lpSystemAffinityMask)

;The default should be all CPU work on a process, so hyperthreading CPUs should return 3 (CPU0+virtual CPU1)
;The System Affinity Mask basically is the number of CPUs, aka the maximum. You can do some bitshifting if
;you want to retrieve the number of CPUs.
Debug lpProcessAffinityMask
Debug lpSystemAffinityMask

;Now specify the CPU the process shall run on
Result = SetProcessAffinityMask_ (pHandle,CustomAffinity)

;a very intersting variant of this is
;SetThreadAffinityMask_(threadHandle,dwThreadAffinityMask)
;which allows to spread different threads to specific CPUs in order to maximize Performance in multiprocessor
;systems
Edit: oops, a typo in variable declaration

Posted: Fri Jul 29, 2005 12:07 am
by Shannara
This is exactly what I have been looking for, for what I am working on :) One thread for graphics rendering, different threads for loading/saving data, and another thread for handling socket requests ;) This is perfect! Thank you!

Posted: Fri Jul 29, 2005 11:42 pm
by Sub-Routine
Interesting, but...

I don't understand why you would want to lock a task to a specific CPU unless they were of different speeds.

Rand

Posted: Sat Jul 30, 2005 12:02 am
by Shannara
Hmm, I read the pb manual and it turns out due to a DX limitation, you cant assign rendering to a thread.. bah!

Anyways, one of the reasons would be having one cpu do, say, loading a map in the background or a huge file, while the other does the window refreshing.

Or ..

different cpus loading different amounts of data at the same time ... or ... for server side, have one thread deal with npc AI which can be majorly intensive, while another thread handles parsing data from a client.

Posted: Sat Jul 30, 2005 12:03 am
by Max.
Sub-Routine wrote:Interesting, but...

I don't understand why you would want to lock a task to a specific CPU unless they were of different speeds.
- 2 CPU are never 2 times as fast as 1, as the management causes some overhead. If a process tries to use 2 CPU though the application is not programmed to utitlize both, you can be slowed down due to the overhead. Restricting the process to 1 CPU can gain you some performance.

- There are issues where some programs might fail, using more than 1 processor - even if the 2nd one is virtual (HT). Firefox is such an example, which can have problems.

- Closely related; other issues that are recently developed are with dual core CPU like the new AMD. some programs get screwed up. There are even online games which require you to set the CPU affinity to 1 CPU manually, as you could gain some unfair advantage over others that is beyond the scope of "Just a better PC".

- if an application is not developed to utilitze all available CPU for the different tasks, you won't experience too much gain. The OS does not take care of doing that. SetThreadAffinityMask is the way to go to get the maximum.

Posted: Sat Jul 30, 2005 1:24 am
by Sub-Routine
Max. wrote:
Sub-Routine wrote:Interesting, but...

I don't understand why you would want to lock a task to a specific CPU unless they were of different speeds.
- 2 CPU are never 2 times as fast as 1, as the management causes some overhead. If a process tries to use 2 CPU though the application is not programmed to utitlize both, you can be slowed down due to the overhead. Restricting the process to 1 CPU can gain you some performance.

- There are issues where some programs might fail, using more than 1 processor - even if the 2nd one is virtual (HT). Firefox is such an example, which can have problems.

- Closely related; other issues that are recently developed are with dual core CPU like the new AMD. some programs get screwed up. There are even online games which require you to set the CPU affinity to 1 CPU manually, as you could gain some unfair advantage over others that is beyond the scope of "Just a better PC".

- if an application is not developed to utilitze all available CPU for the different tasks, you won't experience too much gain. The OS does not take care of doing that. SetThreadAffinityMask is the way to go to get the maximum.
Now it is verrry interesting...

Taking command of this 2.8 MHz Pentium D, dual core processor, about two weeks ago has given me some challenges. I expected the OS to assign a process to one or the other (first available) CPU and keep it there for the duration of the process.

Firefox and a few other programs have been a bit flaky, even many Windows processes, like Copy and Paste.

Hopefully all the glitches will be worked out soon.

Thank you,
Rand

Posted: Sat Jul 30, 2005 8:38 am
by Max.
You might want to google for imagecfg

This program modifies an executable so it is bound to a specific cpu permanently.