Change affinity of process with windows script
Asked Answered
D

4

24

In Windows, with

 START /node 1 /affinity ff cmd /C "app.exe"

I can set the affinity of app.exe (number of cores used by app.exe).

With a windows script, How I can change the affinity of a running process ?

Define answered 4/10, 2013 at 17:23 Comment(0)
M
28

PowerShell can do this task for you.

Get Affinity
$Process = Get-Process app
$Process | Select-Object ProcessorAffinity
Set Affinity
$Process = Get-Process app
$Process.ProcessorAffinity = 255

Example ( 8 Core Processor )

Core # Value BitMask
Core 1 1 0x00000001
Core 2 2 0x00000010
Core 3 4 0x00000100
Core 4 8 0x00001000
Core 5 16 0x00010000
Core 6 32 0x00100000
Core 7 64 0x01000000
Core 8 128 0x10000000

Just add the decimal values together for which core you want to use.

  • All 8 Cores = Value: 255 = BitMask: 0x11111111

Using with cmd.exe

You can use the PowerShell code from within the cmd shell by calling the PowerShell process with the code as an argument. Separate commands with a semi-colon.

> powershell.exe "Get-Process notepad++ | Select-Object ProcessorAffinity"

                                                         ProcessorAffinity
                                                         -----------------
                                                                       255


> powershell.exe "$p = Get-Process notepad++; $p.ProcessorAffinity = 13"

> powershell.exe "Get-Process notepad++ | Select-Object ProcessorAffinity"

                                                         ProcessorAffinity
                                                         -----------------
                                                                        13

Source

Here is a nicely detailed post on how to change a process's affinity:

Setting Processor Affinity @ EnergizedTech
archive.today / archive.org
(the broken images weren't important)

Mabellemable answered 4/10, 2013 at 20:48 Comment(4)
the first command works fine. but for the 2nd I get this message: "The property 'ProcessorAffinity' cannot be found on this object. Verify that the property exists and can be set. At line:1 char:32 + $Process = Get-Process chrome; $Process.ProcessorAffinity=1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : PropertyAssignmentException "Dissimilar
How can this be used if there are multiple processes with the same name (e.g., java)? Does it set the affinity of all the java processes, or pick one at random (or lowest pid, etc.)Semiotic
@DanielWiddis Using Get-Process java | ... will change the affinity for all of the java processes. If you just want a specific instance of java, you will have to know and use the process ID. e.g. Get-Process -ID 8500 Otherwise, you will have to implement your own filtering.Mabellemable
Hust a heads-up to anyone reading this via Google that if you don't want to use PowerShell, or need to invoke from a command prompt using the cmd /start "" /Affinity value method, core affinity is actually hexadecimal. e.g., to launch a process using cores 13-16 on a 16-core CPU, the decimal value is 61440 and the hex is 0xF000. Using 61440 will launch a process using cores 6,10 and 12 :-) rapidtables.com/convert/number/binary-to-hex.html is useful for quick conversion.Salmi
D
13

The accepted answer works, but only for the first process in the list. The solution to that in the comments does not work for me.

To change affinity of all processes with the same name use this:

Powershell "ForEach($PROCESS in GET-PROCESS processname) { $PROCESS.ProcessorAffinity=255}"

Where 255 is the mask as given in the accepted answer.

Desultory answered 29/1, 2017 at 16:10 Comment(10)
Need period to be right after the $PROCESS like $PROCESS.ProcessorAffinity=255Sarmentum
true, I changed it.Desultory
This is super verbose; just use Get-Process $processName | % { $_.ProcessorAffinity = $value; };Blanche
Still too verbose: use Get-Process $pn| %{ $_.ProcessorAffinity = $v} /sRochkind
Still too verbose — use (ps $p).ProcessorAffinity=$v /sPapeete
@StarsonHochschild I get two errors with your command. 1. Unexpected token 's', 2. The property 'ProcessorAffinity' cannot be found on this object.. How is your command supposed to be used?Dehart
Guys, if you are confused like me, this is what I ended up with ps $p | %{ $_.ProcessorAffinity = $v } e.g. ps chrome | %{ $_.ProcessorAffinity = 63 }Dehart
@Dehart Look carefully, the /s is not part of the command. It was a "sarcasm" indicator, just like the comment from Dimesio ;)Papeete
@StarsonHochschild One never knows on the internet. I can't know if it's bad formatting, mistake, copypasta or intentional without knowing the context. Anyway, if I remove /s, which I did, I get the error number 2. Is it failing because the object is an array?Dehart
@Dehart Ah, yes, that form is incompatible if ps returns multiple processes. It's better to use your solution which handles both cases. No big deal because like I said I meant that comment more as a continuation of the "too verbose" rather than a real solutionPapeete
M
2

For anyone else looking for answers to this and not finding any, the solution I found was to use an app called WinAFC (or AffinityChanger). This is a partial GUI, partial command line app that allows you to specify profiles for certain executables, and will poll the process list for them. If it finds matching processes, it will change the affinity of those processes according to the settings in the loaded profile.

There is some documentation here: http://affinitychanger.sourceforge.net/

For my purposes, I created a profile that looked like this:

TestMode = 0
TimeInterval = 1
*\convert.exe := PAIR0+PAIR1

This profile sets any convert.exe process to use the first two CPU core pairs (CPU0, CPU1, CPU2, and CPU3), polling every second. TestMode is a toggle that allows you to see if your profile is working without actually setting affinities.

Hope someone finds this useful!

Merylmes answered 5/10, 2016 at 22:55 Comment(2)
I'm find this program a bit patchy. I know it's old, so wondered if you still use it successfully? It looks great, but it picks up some programs and not others.Ailin
It's been SO long since I did this. I know it worked for me at the time. I haven't needed to use the program since then; it was a short-term thing.Merylmes
P
1

If you really like enums, you can do it this way. ProcessorAffinity is an IntPtr, so it takes a little extra type casting.

[flags()] Enum Cores {
  Core1 = 0x0001
  Core2 = 0x0002
  Core3 = 0x0004
  Core4 = 0x0008
  Core5 = 0x0010
  Core6 = 0x0020
  Core7 = 0x0040
  Core8 = 0x0080
}

$a = get-process notepad

[cores][int]$a.Processoraffinity
Core1, Core2, Core3, Core4

$a.ProcessorAffinity = [int][cores]'core1,core2,core3,core4'
Prose answered 2/5, 2019 at 15:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.