Как ограничить процесс одним ядром процессора?


30

Как ограничить запуск одной процессной программы в среде Windows только на одном процессоре на многоядерном компьютере?

То же самое между оконной программой и программой командной строки?

ОБНОВИТЬ:

  • Причина для этого: сравнение различных аспектов языков программирования
  • Мне нужно что-то, что будет работать с самого начала процесса, поэтому ответ @ akseli, хотя и отлично подходит для других случаев, не решает мою проблему

2
почему ты хочешь сделать это? Позволяя ОС решать, какой процессор / ядро ​​работает, какой процесс будет гораздо более эффективным.
ChrisF

1
для того, чтобы сравнить различные аспекты языка программирования
Джонатан

1
Это веская причина - вы должны были включить эту информацию в свой вопрос. Это важно.
ChrisF

Мотивация не важна, но я добавил ее, следуя твоему совету
Джонатан

1
Тем не менее, это может быть информация, которую кто-то должен уметь дать ответ.
ChrisF

Ответы:


27

Если вы используете Windows Vista / 7 (возможно, XP, но не уверены), это действительно довольно просто.

Введите: Control+Shift+Escчтобы получить ваш менеджер задач.

Нажмите на вкладку Процессы

Найти процесс, который нуждается в изменении привязки к процессору

Щелкните правой кнопкой мыши по процессу

Нажмите на «Установить сходство»

Здесь вы можете выбрать, какой процессор (ы) будет использовать ваш процесс.

Удачи!

РЕДАКТИРОВАТЬ: Вы должны быть администратором, чтобы заставить это работать.


13
Сродство не является гарантией. Процессы предпочтут этот процессор, но если он имеет несколько потоков, они не все останутся там.
Джоэл Коухорн

1
Это хорошо, но мне нужно что-то, что будет детерминированным с самого начала
Джонатан

2
@JoelCoehoorn: Нет, это является гарантией. То, о чем вы говорите, - это предпочтительный вектор процессора, который отличается от вектора сродства.
Мердад

1
@Mehrdad: если только сама программа не изменит его на что угодно.
Евгений Рябцев

1
@JoelCoehoorn > Привязка к потоку заставляет поток работать на определенном подмножестве процессоров. - вы, кажется, имеете в виду то, что в этой статье написано, что это идеальный процессор потоков .
Боб

19

из командной строки используйте

start / affinity 1 program.exe

это запустит program.exe на первом процессоре, так как «1» является шестнадцатеричным значением маски сходства

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 

1
Revolter: Знаете ли вы, могу ли я сделать то же самое с инициализацией служб?
Диого

Что делать, если у вас более 4 ядер?
posfan12

7

Зависит от того, что вы готовы сделать:

Способ 1: по требованию

Используйте ImageCFG . Эта утилита позволит вам настроить исполняемый файл для запуска на любом количестве ядер. Убедитесь, что вы сделали резервную копию вашего целевого исполняемого файла перед внесением изменений и восстановите его, когда закончите играть с ним.

Способ 2: принудительная сессия Windows (Vista / 7)

  1. Введите bcdedit /set onecpu onв командной строке
  2. Перезагрузите систему.
  3. Когда вы закончите играть, введите 2 - Тип: bcdedit /set onecpu offи перезагрузите компьютер снова.

Способ 2: форсировать весь сеанс Windows (XP)

  1. Откройте файл boot.ini (щелкните правой кнопкой мыши «Мой компьютер» -> «Свойства» -> вкладка «Дополнительно» -> кнопку «Настройки» в разделе «Загрузка и восстановление» -> кнопку «Редактировать» в «Запуск системы»).
  2. Вы найдете следующий (или аналогичный) раздел в файле:

    [операционные системы]

    многодисковый (0) дисковый (0) rdisk (0) раздел (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect

  3. Измените его, добавив флаг / onecpu:

    [операционные системы]

    многодисковый (0) дисковый (0) rdisk (0) раздел (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect / onecpu

  4. Перезагружать. Как только вы закончите играть, снимите флажок и перезагрузите компьютер снова.

Метод 0: не очень хороший метод (сродство процессора)

Боюсь, что-либо, что связано с процессором Affinity, не очень хороший вариант. Сродство процессора - ключ к процессору. Процессор не обязан его уважать и часто не будет.


Способ 2, похоже, не работает на Win7. D:\>bcdedit /set onecpuрезультаты в The set command specified is not valid.....The parameter is incorrect.
максимум

2
technet.microsoft.com/en-us/library/cc938636.aspx говорит "... жесткое сходство, означающее, что маска сходства процессора ограничивает потоки, на которые воздействует маска сходства, процессорами, указанными в маске. Потоки ограничены жестким маска сходства не будет работать на процессорах, которые не включены в маску сходства ". Любой источник говорит, что его не будут уважать?
Евгений Рябцев

4

Я поместил следующую функцию в моей программе в Python 2.6, и она вызывает функции Windows. У моей машины только два ядра, поэтому вам может потребоваться изменить эту часть. В комментариях рассказывается, как увидеть текущее сходство. Он работает "как есть" для одноядерного компьютера, если вы установите или по умолчанию установите маску на 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

Не уверен, если ОП попросил код ...
bytebuster

Как вы выполняете эту функцию из командной строки или командного файла? Есть ли способ узнать или установить заранее, каким будет идентификатор процесса?
posfan12

4

В Windows 8 вам нужно перейти на вкладку Details диспетчера задач, чтобы установить Set Affinity. Это не дает вам возможность на вкладке Процессы.

РЕДАКТИРОВАТЬ: Кроме того, если программа, которую вы хотите запустить, имеет параметры, этот поток может пригодиться: Как запустить программу с аргументами командной строки в Windows 'cmd с командой' start '?


4

Когда я искал очень похожую информацию с помощью PowerShell, я нашел нужную информацию здесь: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

Вы не упомянули, какую операционную систему Windows вы использовали (старые версии не поставлялись с PowerShell, хотя вы можете установить ее, если ее там нет).

Самое быстрое, что в PowerShell сходство процессов - это просто свойство, которое вы можете легко изменить.

Чтобы увидеть свойства (и другие подробности) вашего процесса (используя foo в качестве примера процесса), команда PowerShell должна быть:

Get-Process Foo | Get-Member

Вы увидите, что ProcessorAffinity является одним из этих свойств. Его изменение тривиально, и вы можете выбрать ядро, на котором хотите работать, используя значения из таблицы / ссылки Revolter выше.

Чтобы увидеть, что значение свойства ProcessorAffinity для foo, вот команда:

(Get-Process foo) .ProcessorAffinity

Поэтому, если вы хотите запустить foo только на процессоре 4, вы должны установить значение следующим образом:

(Get-Process foo) .ProcessorAffinity = 8


Я не могу сказать из вашего объяснения: это относится только к существующим процессам? ОП не хочет запускать процесс и затем устанавливать его сходство; он хочет начать процесс с уже установленным сродством , как в start /affinityответе. Может ли ваша техника сделать это? Если это так, пожалуйста, объясните, как.
Скотт

2
@Scott Только существующие процессы. В предоставленном вами контексте мой ответ не поможет. Я чувствовал, что «само начало процесса» было вопросом запуска процесса, а затем немедленного установления его сродства. IE: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8 Однако, прочитав ваш комментарий и обнаружив, что Start-Processсам флаг пропущен, я пришел к следующему, которое я протестировал: [System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010
Bewc

Я предлагаю вам отредактировать свой ответ, чтобы добавить эту альтернативу.
Скотт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.