How to limit a process to a single CPU core?

31

16

How do you limit a single process program run in a Windows environment to run only on a single CPU on a multi-core machine?

Is it the same between a windowed program and a command line program?

UPDATE:

  • Reason for doing this: benchmarking various programming languages aspects
  • I need something that would work from the very start of the process, therefore @akseli's answer, although great for other cases, doesn't solve my case

Jonathan

Posted 2011-07-12T13:20:58.123

Reputation: 3 371

2Why do you want to do this? Letting the OS decide which CPU/core runs which process it going to be much more efficient. – ChrisF – 2011-07-12T13:24:29.870

1in order to benchmark various programming language aspects – Jonathan – 2011-07-12T14:00:30.913

1That's a good reason - you should have included that information in your question. It's important. – ChrisF – 2011-07-12T14:08:50.440

Motivation isn't essential, but I added it following your advice – Jonathan – 2011-07-12T14:38:46.623

1However, it might be the information someone needs to be able to provide an answer. – ChrisF – 2011-07-12T14:39:28.230

Answers

27

If you're running Windows Vista/7 (possibly XP, but not sure) it's really rather simple.

Type in: Control+Shift+Esc to get your taskmanager up.

Click on the Processes tab

Find the process that needs its processor affinity changed

Right-click on the process

Click on "Set Affinity"

Here you can select which processor(s) your process will use.

Good luck!

EDIT: You have to be administrator to get this to work.

akseli

Posted 2011-07-12T13:20:58.123

Reputation: 3 796

1

@JoelCoehoorn > Thread affinity forces a thread to run on a specific subset of processors. - you seem to be referring to what that article says is a thread ideal processor.

– Bob – 2015-04-21T08:49:28.650

Really nice, i didn't know that. Good answear +1 for me. – Diogo – 2011-07-12T13:26:59.603

13An affinity is not a guarantee. The processes will prefer this processor, but if it has several threads they won't all stay there. – Joel Coehoorn – 2011-07-12T13:40:47.173

It's not a guarantee but it's a beginning. You can also maximise your probabily of getting the processor you've set the afinity for if you set logical affinities for your most processor-hungry tasks. – akseli – 2011-07-12T13:43:35.913

1This is good, but I need something that will be deterministic right from the start – Jonathan – 2011-07-12T14:01:31.663

2@JoelCoehoorn: No, it is a guarantee. What you're talking about is the preferred processor vector, which is different from the affinity vector. – user541686 – 2013-02-18T06:10:53.600

1@Mehrdad: unless the program itself changes it to whatever it will. – Eugene Ryabtsev – 2013-11-28T04:49:48.747

20

from the command line, use

start /affinity 1 program.exe

this will run program.exe on the first CPU as "1" is the hex value of the affinity mask

CPU3 CPU2 CPU1 CPU0  Bin  Hex
---- ---- ---- ----  ---  ---
OFF  OFF  OFF  ON  = 0001 = 1
OFF  OFF  ON   OFF = 0010 = 2
OFF  OFF  ON   ON  = 0011 = 3
OFF  ON   OFF  OFF = 0100 = 4
OFF  ON   OFF  ON  = 0101 = 5 
OFF  ON   ON   OFF = 0110 = 6
OFF  ON   ON   ON  = 0111 = 7
ON   OFF  OFF  OFF = 1000 = 8
ON   OFF  OFF  ON  = 1001 = 9
ON   OFF  ON   OFF = 1010 = A 
ON   OFF  ON   ON  = 1011 = B
ON   ON   OFF  OFF = 1100 = C
ON   ON   OFF  ON  = 1101 = D
ON   ON   ON   OFF = 1110 = E 
ON   ON   ON   ON  = 1111 = F 

user8228

Posted 2011-07-12T13:20:58.123

Reputation:

What if you have more than 4 cores? – posfan12 – 2018-03-05T02:17:49.127

1Revolter: Do you know if I can do the same with Services initialization? – Diogo – 2011-07-13T11:51:37.490

6

Depends on what you are willing to do:

Method 1: On demand

Use ImageCFG. This utility will let you setup an executable to run on any number of cores. Make sure you backup your target executable before making the changes and restore it when you are done playing with it.

Method 2: Force an entire Windows Session (Vista/7)

  1. Type bcdedit /set onecpu on on a command prompt
  2. Reboot the system.
  3. When you are done playing, type 2 - Type: bcdedit /set onecpu off and reboot again.

Method 2: Force an entire Windows Session (XP)

  1. Open your boot.ini file (Right-click My Computer -> Properties -> Advanced Tab -> Settings button under 'Startup and Recovery' -> Edit button in 'System Startup').
  2. You'll find the following (or similar) section in the file:

    [operating systems]

    multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional" /fastdetect

  3. Change it by adding the /onecpu flag:

    [operating systems]

    multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional" /fastdetect /onecpu

  4. Reboot. Once you are done playing remove the flag and reboot again.

Method 0: Not a good method (Processor Affinity)

Anything that otherwise involves Processor Affinity isn't a good option, I'm afraid. Processor affinity is a clue to the processor. The processor is not obliged to respect it, and often will not.

A Dwarf

Posted 2011-07-12T13:20:58.123

Reputation: 17 756

Method 2 doens't seem to work on Win7. D:\>bcdedit /set onecpu results in The set command specified is not valid..... The parameter is incorrect. – max – 2012-10-12T06:19:17.487

2http://technet.microsoft.com/en-us/library/cc938636.aspx says "... hard affinity, meaning that the processor affinity mask restricts the threads affected by the affinity mask to the processors specified by the mask. Threads restricted by a hard affinity mask will not run on processors that aren't included in the affinity mask". Any source saying it is not going to be respected? – Eugene Ryabtsev – 2013-11-28T04:56:45.867

5

I put the following function in my program in python 2.6 and it calls windows functions. My machine has only two cores so you may need to change that part. The comments tell you how to see what the current affinity is. It works "as is" for a single core machine if you set or default to a mask of 1.

def setaffinitymask(pid = None, mask = 1):
    """ Set The Affinity Mask of a Windows Process.  Affinity Mask is a value between 1-3 where
        1 is for core 0, 2 is for core 1, 3 is for both cores (it is a bitmap)
        Default sets the Affinity Mask to core 0 only
        python process can take any valid process ID. """

    import win32api, win32process, win32con

    if pid  == None:
        pid  = win32api.GetCurrentProcessId()
    if mask == None:
        mask = 1
    if mask  < 1 or mask > 3:
        mask = 1
        print 'process affinity mask out of range [1..3] setting it to 1'
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    # see what mask is currently set to
    # processAffinityMask, systemAffinityMask = win32process.GetProcessAffinityMask(handle)
    # print 'process affinity mask = ', processAffinityMask, ', system affinity mask = ', systemAffinityMask
    # set affinity for process to mask value
    win32process.SetProcessAffinityMask(handle, mask) # 1=core 0, 2=core 1, 3=both
    processAffinityMask, systemAffinityMask = win32process.GetProcessAffinityMask(handle)
    #print 'process affinity mask = ', processAffinityMask, ', system affinity mask = ', systemAffinityMask

Marichyasana

Posted 2011-07-12T13:20:58.123

Reputation: 181

How do you execute this function from the command line or batch file? Is there a way to know or set beforehand what the process ID will be? – posfan12 – 2018-03-05T02:22:27.060

Not sure if OP asked for a code... – bytebuster – 2012-12-15T22:59:46.063

4

In Windows 8, you have to go to the Details tab of the task manager to do Set Affinity. It doesn't give you the option on the Processes tab.

EDIT: Also, if the program you want to start has parameters, this thread could come in handy: How to start a program with command line arguments on Windows' cmd with 'start' command?

DLeh

Posted 2011-07-12T13:20:58.123

Reputation: 214

4

As I went looking for very similar information using PowerShell, I found the information I needed here: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

You didn't mention which Windows OS you were using, (The older ones didn't come with PowerShell, although you could install it if it's not there).

The quick of it, is that in PowerShell, process affinity is simply a property you can change easily.

To see the properties (and other tidbits of info) of your process (using foo as an example process), the PowerShell command would be:

Get-Process foo | Get-Member

You'll see ProcessorAffinity is one of those properties. Changing it is trivial, and you can select which core you want to run on, using the values from Revolter's table/link above.

To see what the value of the ProcessorAffinity property is for foo, here's the command:

(Get-Process foo).ProcessorAffinity

So if you wanted to run foo on cpu 4 only, you would set the value as such:

(Get-Process foo).ProcessorAffinity=8

Bewc

Posted 2011-07-12T13:20:58.123

Reputation: 228

I can’t tell from your explanation: does this apply only to existing processes?  The OP doesn’t want to start a process and then set its affinity; he wants to start a process *with its affinity already set*, as in the start /affinity answer.  Can your technique do that?  If so, please explain how. – Scott – 2013-07-23T23:33:04.693

2@Scott Existing processes only. In the context you provide, my answer doesn't help. I felt that the "very start of the process", was a matter of starting the process & then immediately setting its affinity. I.E.: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8

However, after reading your comment, and finding that Start-Process has a missing affinity flag itself, I came up with the following, which I tested:

[System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010 – Bewc – 2013-08-26T21:00:57.263

I suggest that you edit your answer to add that alternative. – Scott – 2013-08-27T22:36:42.943