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


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.