По умолчанию запущенное в Windows приложение может выполняться на любом из ядер процессора, а распределением процессорных мощностей занимается операционная система. Обычно она неплохо справляется с этой задачей, но иногда все же требуется ручная настройка. Для этой цели в Windows есть функционал Processor Affinity, который позволяет осуществлять привязку вычислительных процессов к ядрам процессора.
При помощи этого функционала можно указать сходство (affinity) процесса с определенными ядрами процессора, тем самым привязав процесс к этим ядрам. Если вы установили для процесса привязку к определенным ядрам, то он будет выполняться только на этих ядрах.
В какой ситуации может потребоваться настройка Processor Affinity:
• Для ограничения потребления ресурсов конкретным приложением. Самый простой и эффективный, хотя и достаточно грубый способ ограничить для приложения потребляемую процессорную мощность.
• Для обеспечения совместимости. К примеру требуется запустить устаревшее приложение, которое работает некорректно в многопроцессорной системе.
• Для повышения производительности. В случае с ресурсоемкими приложениями (напр. рендеринг видео) иногда рекомендуют выделить программе отдельные ядра процессора. Это гарантирует, что ядра будут всегда доступны для выполнения задачи и не будет задержек, связанных с выбором и переключением между ядрами.
Проще всего осуществить привязку с помощью диспетчера задач (Task Manager). Для этого надо на вкладке Details (Подробности) найти нужный процесс, кликнуть на нем правой клавишей мыши и в контекстном меню выбрать пункт Set Affinity (Задать сходство).
В открывшемся окне буду показаны все имеющиеся ядра процессора. Те, которые процесс может использовать, отмечены галочкой. Для изменения просто убираем галочку с ненужных ядер и жмем ОК.
Можно осуществлять привязку и с помощью PowerShell. Для примера запустим Блокнот (notepad) и выведем его текущее значение командой:
Get-Process notepad | fl ProcessorAffinity
А теперь давайте разберемся, откуда взялась цифра 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
Проверим результат и в графической оснастке. Как видите, нашему процессу сопоставлены три ядра процессора, как и было задумано 🙂
Таким образом можно осуществить привязку уже запущенного процесса, а можно ли запустить процесс сразу с привязкой к определенным ядрам? Можно, с помощью утилиты командной строки start с ключом /affinity. Например, для запуска блокнота с привязкой к первому ядру достаточно выполнить команду:
start /affinity 1 notepad
Эта команда отлично работает в командной консоли, но если вы попытаетесь выполнить ее при помощи PowerShell, то получите ошибку. Дело в том, что в PowerShell команда start является алиасом для командлета Start-Command, для которого указанные параметры являются недопустимыми.
Поэтому, если все же требуется запуск именно из 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 изменить соответствие ядрам