¿Cómo limitar un proceso a un solo núcleo de CPU?

30

¿Cómo se limita la ejecución de un solo programa de proceso en un entorno Windows para que se ejecute solo en una sola CPU en una máquina de múltiples núcleos?

¿Es lo mismo entre un programa en ventana y un programa de línea de comando?

ACTUALIZAR:

  • Razón para hacerlo: evaluación comparativa de varios aspectos de lenguajes de programación
  • Necesito algo que funcione desde el comienzo del proceso, por lo tanto, la respuesta de @ akseli, aunque excelente para otros casos, no resuelve mi caso
Jonathan
fuente
2
¿Por qué quieres hacer esto? Dejar que el sistema operativo decida qué CPU / núcleo se ejecuta y qué proceso será mucho más eficiente.
ChrisF
1
para comparar varios aspectos del lenguaje de programación
Jonathan
1
Esa es una buena razón: debería haber incluido esa información en su pregunta. Es importante.
ChrisF
La motivación no es esencial, pero la agregué siguiendo tu consejo
Jonathan
1
Sin embargo, podría ser la información que alguien necesita para poder proporcionar una respuesta.
ChrisF

Respuestas:

27

Si está ejecutando Windows Vista / 7 (posiblemente XP, pero no estoy seguro) es realmente bastante simple.

Escriba: Control+Shift+Escpara activar su administrador de tareas.

Haga clic en la pestaña Procesos

Encuentre el proceso que necesita cambiar su afinidad de procesador

Haga clic derecho en el proceso

Haga clic en "Establecer afinidad"

Aquí puede seleccionar qué procesador (s) utilizará su proceso.

¡Buena suerte!

EDITAR: Tienes que ser administrador para que esto funcione.

akseli
fuente
13
Una afinidad no es una garantía. Los procesos preferirán este procesador, pero si tiene varios subprocesos, no todos permanecerán allí.
Joel Coehoorn
1
Esto es bueno, pero necesito algo que sea determinista desde el principio
Jonathan
2
@ JooCoehoorn: No, es una garantía. De lo que estás hablando es del vector de procesador preferido , que es diferente del vector de afinidad.
Mehrdad
1
@Mehrdad: a menos que el programa lo cambie a lo que sea.
Eugene Ryabtsev
1
@JoelCoehoorn > La afinidad del subproceso obliga a un subproceso a ejecutarse en un subconjunto específico de procesadores. - Parece que te refieres a lo que ese artículo dice es un procesador de hilo ideal .
Bob
19

desde la línea de comando, use

start / affinity 1 program.exe

esto ejecutará program.exe en la primera CPU ya que "1" es el valor hexadecimal de la máscara de afinidad

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 

fuente
1
Revolter: ¿Sabes si puedo hacer lo mismo con la inicialización de Servicios?
Diogo
¿Qué pasa si tienes más de 4 núcleos?
posfan12
7

Depende de lo que estés dispuesto a hacer:

Método 1: bajo demanda

Use ImageCFG . Esta utilidad te permitirá configurar un ejecutable para que se ejecute en cualquier número de núcleos. Asegúrese de hacer una copia de seguridad de su ejecutable de destino antes de realizar los cambios y restaurarlo cuando haya terminado de jugar con él.

Método 2: forzar una sesión de Windows completa (Vista / 7)

  1. Escriba bcdedit /set onecpu onen el símbolo del sistema
  2. Reinicia el sistema.
  3. Cuando termine de jugar, escriba 2 - Escriba: bcdedit /set onecpu offy reinicie nuevamente.

Método 2: forzar una sesión de Windows completa (XP)

  1. Abra su archivo boot.ini (haga clic con el botón derecho en Mi PC -> Propiedades -> Pestaña Avanzada -> botón Configuración en 'Inicio y recuperación' -> botón Editar en 'Inicio del sistema').
  2. Encontrará la siguiente sección (o similar) en el archivo:

    [sistemas operativos]

    partición de disco múltiple (0) (0) rdisk (0) (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect

  3. Cámbielo agregando el indicador / onecpu:

    [sistemas operativos]

    partición multi (0) disco (0) rdisk (0) (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect / onecpu

  4. Reiniciar. Una vez que hayas terminado de jugar, elimina la bandera y reinicia nuevamente.

Método 0: no es un buen método (afinidad del procesador)

Me temo que cualquier cosa que implique la afinidad del procesador no es una buena opción. La afinidad del procesador es una pista para el procesador. El procesador no está obligado a respetarlo, y a menudo no lo hará.

Un enano
fuente
El método 2 no parece funcionar en Win7. D:\>bcdedit /set onecpuresultados en The set command specified is not valid....The parameter is incorrect.
max
2
technet.microsoft.com/en-us/library/cc938636.aspx dice "... afinidad fuerte, lo que significa que la máscara de afinidad del procesador restringe los hilos afectados por la máscara de afinidad a los procesadores especificados por la máscara. Hilos restringidos por un disco duro la máscara de afinidad no se ejecutará en procesadores que no estén incluidos en la máscara de afinidad ". ¿Alguna fuente dice que no va a ser respetada?
Eugene Ryabtsev
4

Puse la siguiente función en mi programa en Python 2.6 y llama a las funciones de Windows. Mi máquina tiene solo dos núcleos, por lo que es posible que deba cambiar esa parte. Los comentarios le dicen cómo ver cuál es la afinidad actual. Funciona "tal cual" para una máquina de un solo núcleo si configura o establece por defecto una 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
fuente
No estoy seguro si OP solicitó un código ...
bytebuster
¿Cómo ejecuta esta función desde la línea de comando o el archivo por lotes? ¿Hay alguna manera de saber o establecer de antemano cuál será la ID del proceso?
posfan12
4

Mientras buscaba información muy similar usando PowerShell, encontré la información que necesitaba aquí: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

No mencionó qué sistema operativo Windows estaba usando (los más antiguos no venían con PowerShell, aunque podría instalarlo si no está allí).

Lo más rápido es que en PowerShell, la afinidad del proceso es simplemente una propiedad que puede cambiar fácilmente.

Para ver las propiedades (y otros datos de información) de su proceso (usando foo como proceso de ejemplo), el comando PowerShell sería:

Get-Process foo | Obtener miembro

Verá que ProcessorAffinity es una de esas propiedades. Cambiarlo es trivial, y puede seleccionar en qué núcleo desea ejecutar, utilizando los valores de la tabla / enlace de Revolter arriba.

Para ver cuál es el valor de la propiedad ProcessorAffinity para foo, aquí está el comando:

(Get-Process foo) .ProcessorAffinity

Entonces, si desea ejecutar foo solo en la CPU 4, establecería el valor como tal:

(Get-Process foo) .ProcessorAffinity = 8

Bewc
fuente
No puedo decir por su explicación: ¿esto se aplica solo a los procesos existentes? El OP no quiere iniciar un proceso y luego establecer su afinidad; quiere comenzar un proceso con su afinidad ya establecida , como en la start /affinityrespuesta. ¿Puede tu técnica hacer eso? Si es así, explique cómo.
Scott
2
@Scott Solo procesos existentes. En el contexto que proporcione, mi respuesta no ayuda. Sentí que el "comienzo mismo del proceso" era una cuestión de comenzar el proceso y luego establecer inmediatamente su afinidad. IE: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8 Sin embargo, después de leer su comentario y descubrir que Start-Processfalta una marca de afinidad, se me ocurrió lo siguiente, que probé: [System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010
Bewc
Le sugiero que edite su respuesta para agregar esa alternativa.
Scott