Заметки о Windows и других программных продуктах Microsoft...

Настройка Processor Affinity с помощью PowerShell

Настройка Processor Affinity с помощью PowerShell

По умолчанию запущенное в Windows приложение может выполняться на любом из ядер процессора, а распределением процессорных мощностей занимается операционная система. Обычно она неплохо справляется с этой задачей, но иногда все же требуется ручная настройка. Для этой цели в Windows есть функционал Processor Affinity, который позволяет осуществлять привязку вычислительных процессов к ядрам процессора.

При помощи этого функционала можно указать сходство (affinity) процесса с определенными ядрами процессора, тем самым привязав процесс к этим ядрам. Если вы установили для процесса привязку к определенным ядрам, то он будет выполняться только на этих ядрах.

В какой ситуации может потребоваться настройка Processor Affinity:

• Для ограничения потребления ресурсов конкретным приложением. Самый простой и эффективный, хотя и достаточно грубый способ ограничить для приложения потребляемую процессорную мощность.
• Для обеспечения совместимости. К примеру требуется запустить устаревшее приложение, которое работает некорректно в многопроцессорной системе.
• Для повышения производительности. В случае с ресурсоемкими приложениями (напр. рендеринг видео) иногда рекомендуют выделить программе отдельные ядра процессора. Это гарантирует, что ядра будут всегда доступны для выполнения задачи и не будет задержек, связанных с выбором и переключением между ядрами.

Проще всего осуществить привязку с помощью диспетчера задач (Task Manager). Для этого надо на вкладке Details (Подробности) найти нужный процесс, кликнуть на нем правой клавишей мыши и в контекстном меню выбрать пункт Set Affinity (Задать сходство).

процессы в Task Manager

 

В открывшемся окне буду показаны все имеющиеся ядра процессора. Те, которые процесс может использовать, отмечены галочкой. Для изменения просто убираем галочку с ненужных ядер и жмем ОК.

Processor Affinity в Task Manager

 

Можно осуществлять привязку и с помощью PowerShell. Для примера запустим Блокнот (notepad) и выведем его текущее значение командой:

Get-Process notepad | fl ProcessorAffinity

Processor Affinity в PowerShell

 

А теперь давайте разберемся, откуда взялась цифра 15. Дело в том, что ProcessorAffinity представляет из себя битовую маску (bitmask), где каждому биту соответствует ядро процессора. Если для ядра отмечено сходство (affinity), то бит выставляется в 1, если нет — то в 0. В нашем случае отмечены все ядра, поэтому маска выглядит так:

CPU3 CPU2 CPU1 CPU0
1   1   1   1  

 

Примечание. При использовании технологии HyperThreading каждое физическое ядро определяется операционной системой как два отдельных процессора (два логических ядра).

Теперь переведем двоичные значения в десятичные и получим:

CPU  BitMask Dec
CPU0 0001 1 (20)
CPU1 0010 2 (21)
CPU2 0100 4 (22)
CPU3 1000 8 (23)

 

Складываем полученные десятичные значения и получаем:

1 + 2 + 4 +8 = 15

Таким образом число 15 означает, что используются все 4 ядра процессора. Если мы хотим это изменить и привязать процесс к определенным ядрам, то складываем только те значения, которые соответствуют этим ядрам. Например, требуется привязать процесс к первым трем ядрам, соответственно значение будет складываться так:

1 + 2 + 4 = 7

Значение получено, теперь осуществим привязку. Для этого выполним следующие команды:

$process = Get-Process notepad
$process.ProcessorAffinity = 7

Изменение Processor Affinity в PowerShell

 

Проверим результат и в графической оснастке. Как видите, нашему процессу сопоставлены три ядра процессора, как и было задумано 🙂

Processor Affinity в Task Manager

 

Таким образом можно осуществить привязку уже запущенного процесса, а можно ли запустить процесс сразу с привязкой к определенным ядрам? Можно, с помощью утилиты командной строки start с ключом /affinity. Например, для запуска блокнота с привязкой к первому ядру достаточно выполнить команду:

start /affinity 1 notepad

Эта команда отлично работает в командной консоли, но если вы попытаетесь выполнить ее при помощи PowerShell, то получите ошибку. Дело в том, что в PowerShell команда start является алиасом для командлета Start-Command, для которого указанные параметры являются недопустимыми.

запуск утилиты start в PowerShell

 

Поэтому, если все же требуется запуск именно из PowerShell, то команду придется немного видоизменить. Например так:

Invoke-Command -ScriptBlock {cmd /c start /affinity 1 notepad}

запуск приложения с заданной привязкой

 

Указывать значение маски в данном случае надо не в десятичном, а в шестнадцатеричном виде. К примеру десятичное значение 15 в шестнадцатеричном виде будет равно F, а команда для запуска процесса с привязкой к четырем ядрам будет выглядеть так:

Invoke-Command -ScriptBlock {cmd /c start /affinity F notepad}

запуск приложения с заданной привязкой

 

И еще, если требуется уточнить количество ядер процессора, то это можно сделать с помощью переменной окружения, командой:

$env:NUMBER_OF_PROCESSORS

просмотр количества ядер

 

 
 
Комментарии

Спасибо! Давно искал эту информацию, как именно через powershell изменить соответствие ядрам

Константин

Добрый день!
А можете подсказать как результат из PowerShell передать в VB NET в DataGridView?

не работает для svchost

Ответить