Como limitar um processo a um único núcleo da CPU?

30

Como você limita um programa de processo único executado em um ambiente Windows para executar apenas em uma única CPU em uma máquina com vários núcleos?

É o mesmo entre um programa em janela e um programa de linha de comando?

ATUALIZAR:

  • Motivo para fazer isso: comparando vários aspectos das linguagens de programação
  • Eu preciso de algo que funcione desde o início do processo, portanto, a resposta da @ akseli, apesar de ótima para outros casos, não resolve o meu caso
Jonathan
fonte
2
Por que você quer fazer isso? Deixar o sistema operacional decidir qual CPU / núcleo será executado e qual processo será muito mais eficiente.
ChrisF
1
A fim de aferir vários aspectos da linguagem de programação
Jonathan
1
Essa é uma boa razão - você deveria ter incluído essas informações na sua pergunta. É importante.
ChrisF
A motivação não é essencial, mas eu a adicionei seguindo o seu conselho
Jonathan
1
No entanto, pode ser a informação que alguém precisa para poder fornecer uma resposta.
31411 ChrisF em

Respostas:

27

Se você estiver executando o Windows Vista / 7 (possivelmente XP, mas não tenho certeza), é realmente bastante simples.

Digite: Control+Shift+Escpara obter seu gerenciador de tarefas.

Clique na guia Processos

Encontre o processo que precisa de sua afinidade de processador alterada

Clique com o botão direito do mouse no processo

Clique em "Definir afinidade"

Aqui você pode selecionar quais processadores o seu processo usará.

Boa sorte!

EDIT: Você precisa ser administrador para que isso funcione.

akseli
fonte
13
Uma afinidade não é uma garantia. Os processos preferem esse processador, mas se ele tiver vários threads, nem todos ficarão lá.
Joel Coehoorn
1
Isso é bom, mas eu preciso de algo que vai ser bom determinista desde o início
Jonathan
2
@JoelCoehoorn: Não, é uma garantia. O que você está falando é o vetor de processador preferido , que é diferente do vetor de afinidade.
Mehrdad
1
@ Mehrdad: a menos que o próprio programa o altere para o que quiser.
Eugene Ryabtsev 28/11
1
@JoelCoehoorn > A afinidade de encadeamento força um encadeamento a ser executado em um subconjunto específico de processadores. - você parece estar se referindo ao que esse artigo diz ser um processador ideal para threads .
Bob
19

na linha de comando, use

start / affinity 1 program.exe

isso executará o programa.exe na primeira CPU, pois "1" é o valor hexadecimal da máscara de afinidade

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 

fonte
1
Revolter: Você sabe se posso fazer o mesmo com a inicialização dos Serviços?
Diogo
E se você tiver mais de 4 núcleos?
posfan12
7

Depende do que você está disposto a fazer:

Método 1: Sob demanda

Use ImageCFG . Este utilitário permitirá que você configure um executável para executar em qualquer número de núcleos. Certifique-se de fazer backup do executável de destino antes de fazer as alterações e restaurá-lo quando terminar de brincar com ele.

Método 2: forçar uma sessão inteira do Windows (Vista / 7)

  1. Digite bcdedit /set onecpu onem um prompt de comando
  2. Reinicie o sistema.
  3. Quando terminar de digitar, digite 2 - Digite: bcdedit /set onecpu offe reinicie novamente.

Método 2: forçar uma sessão inteira do Windows (XP)

  1. Abra o arquivo boot.ini (clique com o botão direito do mouse em Meu computador -> Propriedades -> Guia Avançado -> botão Configurações em 'Inicialização e recuperação' -> botão Editar em 'Inicialização do sistema').
  2. Você encontrará a seguinte seção (ou similar) no arquivo:

    [sistemas operacionais]

    partição multi (0) disco (0) rdisk (0) (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect

  3. Altere-o adicionando o sinalizador / onecpu:

    [sistemas operacionais]

    partição multi (0) disco (0) rdisk (0) (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect / onecpu

  4. Reinicie. Quando terminar de jogar, remova a bandeira e reinicie novamente.

Método 0: Não é um bom método (afinidade do processador)

Receio que qualquer coisa que envolva afinidade do processador não seja uma boa opção. A afinidade do processador é uma pista para o processador. O processador não é obrigado a respeitá-lo, e muitas vezes não o fará.

Um anão
fonte
O método 2 parece não funcionar no Win7. D:\>bcdedit /set onecpuresulta em The set command specified is not valid.....The parameter is incorrect.
max
2
technet.microsoft.com/en-us/library/cc938636.aspx diz "... afinidade total, o que significa que a máscara de afinidade do processador restringe os segmentos afetados pela máscara de afinidade aos processadores especificados pela máscara. a máscara de afinidade não será executada em processadores que não estão incluídos na máscara de afinidade ". Alguma fonte dizendo que isso não será respeitado?
Eugene Ryabtsev 28/11
4

Eu coloquei a seguinte função no meu programa em python 2.6 e ele chama funções do Windows. Minha máquina possui apenas dois núcleos, portanto, pode ser necessário alterar essa parte. Os comentários mostram como ver qual é a afinidade atual. Funciona "como está" para uma máquina de núcleo único se você definir ou usar como padrão uma máscara de 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
Marichyasana
fonte
Não tenho certeza se OP pediu um código ...
bytebuster
Como você executa esta função na linha de comando ou no arquivo em lotes? Existe uma maneira de saber ou definir de antemão qual será o ID do processo?
posfan12
4

Enquanto procurava informações muito semelhantes usando o PowerShell, encontrei as informações necessárias aqui: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

Você não mencionou qual sistema operacional Windows estava usando (os mais antigos não vieram com o PowerShell, embora você possa instalá-lo se ele não estiver lá).

A rápida é que, no PowerShell, a afinidade do processo é simplesmente uma propriedade que você pode alterar facilmente.

Para ver as propriedades (e outras informações) do seu processo (usando foo como um processo de exemplo), o comando do PowerShell seria:

Get-Process foo | Get-Member

Você verá que ProcessorAffinity é uma dessas propriedades. Mudá-lo é trivial e você pode selecionar em qual núcleo deseja executar, usando os valores da tabela / link do Revolter acima.

Para ver qual é o valor da propriedade ProcessorAffinity para foo, aqui está o comando:

(Get-Process foo) .ProcessorAffinity

Portanto, se você quiser executar foo apenas na CPU 4, defina o valor da seguinte forma:

(Get-Process foo) .ProcessorAffinity = 8

Bewc
fonte
Não sei pela sua explicação: isso se aplica apenas aos processos existentes? O OP não deseja iniciar um processo e depois definir sua afinidade; ele quer iniciar um processo com sua afinidade já definida , como na start /affinityresposta. Sua técnica pode fazer isso? Se sim, por favor, explique como.
Scott
2
@Scott Apenas processos existentes. No contexto que você fornece, minha resposta não ajuda. Eu senti que o "início do processo" era uma questão de iniciar o processo e então definir imediatamente sua afinidade. IE: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8 No entanto, depois de ler o seu comentário, e descobrir que Start-Processtem em si uma bandeira afinidade faltando, eu vim com o seguinte, que eu testei: [System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010
Bewc
Sugiro que você edite sua resposta para adicionar essa alternativa.
Scott Scott