Come limitare un processo a un singolo core della CPU?


30

Come si limita l'esecuzione di un singolo programma di processo in un ambiente Windows per l'esecuzione su una singola CPU su un computer multi-core?

È lo stesso tra un programma con finestre e un programma da riga di comando?

AGGIORNARE:

  • Motivo per farlo: analisi comparativa di vari aspetti dei linguaggi di programmazione
  • Ho bisogno di qualcosa che funzioni dall'inizio del processo, quindi la risposta di @ akseli, anche se ottima per altri casi, non risolve il mio caso

2
Perchè vuoi fare questo? Consentire al sistema operativo di decidere quale CPU / core viene eseguito e quale processo sarà molto più efficiente.
ChrisF,

1
al fine di confrontare vari aspetti del linguaggio di programmazione
Jonathan,

1
Questa è una buona ragione: avresti dovuto includere tali informazioni nella tua domanda. È importante.
ChrisF,

La motivazione non è essenziale, ma l'ho aggiunta seguendo i tuoi consigli
Jonathan,

1
Tuttavia, potrebbero essere le informazioni di cui qualcuno ha bisogno per essere in grado di fornire una risposta.
ChrisF,

Risposte:


27

Se stai usando Windows Vista / 7 (possibilmente XP, ma non ne sei sicuro) è davvero piuttosto semplice.

Digita: Control+Shift+Escper attivare il gestore delle attività.

Fai clic sulla scheda Processi

Trova il processo che richiede la modifica dell'affinità del processore

Fare clic con il tasto destro del mouse sul processo

Fai clic su "Imposta affinità"

Qui è possibile selezionare quali processori verranno utilizzati dal processo.

In bocca al lupo!

EDIT: devi essere amministratore per farlo funzionare.


13
Un'affinità non è una garanzia. I processi preferiranno questo processore, ma se ha diversi thread non rimarranno tutti lì.
Joel Coehoorn,

1
Questo va bene, ma ho bisogno di qualcosa che sarà deterministico fin dall'inizio
Jonathan,

2
@JoelCoehoorn: No, è una garanzia. Di cosa stai parlando è il vettore del processore preferito , che è diverso dal vettore di affinità.
Mehrdad,

1
@Mehrdad: a meno che il programma stesso non lo cambi come vuole.
Eugene Ryabtsev,

1
@JoelCoehoorn > L'affinità di thread forza l'esecuzione di un thread su un sottoinsieme specifico di processori. - sembra che ti riferisca a ciò che dice quell'articolo è un processore ideale per i thread .
Bob,

19

dalla riga di comando, utilizzare

start / affinity 1 program.exe

questo eseguirà program.exe sulla prima CPU poiché "1" è il valore esadecimale della maschera di affinità

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: Sai se posso fare lo stesso con l'inizializzazione dei servizi?
Diogo,

E se hai più di 4 core?
posfan12

7

Dipende da cosa sei disposto a fare:

Metodo 1: su richiesta

Usa ImageCFG . Questa utility ti consentirà di configurare un eseguibile per l'esecuzione su qualsiasi numero di core. Assicurati di eseguire il backup del file eseguibile di destinazione prima di apportare le modifiche e ripristinalo quando hai finito di giocarci.

Metodo 2: forzare un'intera sessione di Windows (Vista / 7)

  1. Digitare bcdedit /set onecpu onsu un prompt dei comandi
  2. Riavvia il sistema.
  3. Quando hai finito di giocare, digita 2 - Digita: bcdedit /set onecpu offe riavvia nuovamente.

Metodo 2: forzare un'intera sessione di Windows (XP)

  1. Apri il tuo file boot.ini (fai clic con il pulsante destro del mouse su Risorse del computer -> Proprietà -> Scheda Avanzate -> pulsante Impostazioni in "Avvio e ripristino" -> pulsante Modifica in "Avvio del sistema").
  2. Troverai la seguente (o simile) sezione nel file:

    [sistemi operativi]

    multi (0) disk (0) rdisk (0) partition (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect

  3. Modificalo aggiungendo il flag / onecpu:

    [sistemi operativi]

    multi (0) disk (0) rdisk (0) partition (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect / onecpu

  4. Reboot. Una volta terminata la riproduzione, rimuovere la bandiera e riavviare di nuovo.

Metodo 0: non è un buon metodo (affinità del processore)

Qualunque cosa che coinvolge altrimenti Processor Affinity non è una buona opzione, temo. L'affinità del processore è un indizio per il processore. Il processore non è tenuto a rispettarlo e spesso non lo farà.


Il metodo 2 non sembra funzionare su Win7. D:\>bcdedit /set onecpurisultati in The set command specified is not valid.....The parameter is incorrect.
max

2
technet.microsoft.com/en-us/library/cc938636.aspx dice "... affinità dura, il che significa che la maschera di affinità del processore limita i thread interessati dalla maschera di affinità ai processori specificati dalla maschera. Discussioni limitate da un hard la maschera di affinità non verrà eseguita su processori non inclusi nella maschera di affinità ". Qualche fonte che dice che non sarà rispettata?
Eugene Ryabtsev,

4

Ho messo la seguente funzione nel mio programma in Python 2.6 e chiama le funzioni di Windows. La mia macchina ha solo due core, quindi potrebbe essere necessario cambiare quella parte. I commenti ti dicono come vedere qual è l'attuale affinità. Funziona "così com'è" per una macchina single core se si imposta o imposta automaticamente una maschera di 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

Non sono sicuro che OP abbia richiesto un codice ...
bytebuster,

Come si esegue questa funzione dalla riga di comando o dal file batch? Esiste un modo per sapere o impostare in anticipo quale sarà l'ID processo?
posfan12


4

Mentre cercavo informazioni molto simili usando PowerShell, ho trovato le informazioni di cui avevo bisogno qui: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

Non hai menzionato il sistema operativo Windows che stavi utilizzando (i più vecchi non venivano forniti con PowerShell, anche se potresti installarlo se non fosse presente).

Il fatto è che in PowerShell l'affinità di processo è semplicemente una proprietà che è possibile modificare facilmente.

Per visualizzare le proprietà (e altre informazioni utili) del processo (utilizzando foo come processo di esempio), il comando PowerShell sarebbe:

Get-Process foo | Get-Member

Vedrai ProcessorAffinity è una di quelle proprietà. Modificarlo è banale e puoi selezionare su quale core vuoi eseguire, usando i valori dalla tabella / link di Revolter sopra.

Per vedere qual è il valore della proprietà ProcessorAffinity per pippo, ecco il comando:

(Get-Process foo) .ProcessorAffinity

Quindi, se volessi eseguire foo solo su cpu 4, imposteresti il ​​valore come tale:

(Get-Process foo) .ProcessorAffinity = 8


Non posso dirlo dalla tua spiegazione: questo vale solo per i processi esistenti? L'OP non vuole avviare un processo e quindi impostarne l'affinità; vuole avviare un processo con la sua affinità già impostato , come nella start /affinityrisposta. La tua tecnica può farlo? In tal caso, spiega come.
Scott,

2
@Scott Solo processi esistenti. Nel contesto fornito, la mia risposta non aiuta. Ho sentito che il "vero inizio del processo", era una questione di avviare il processo e quindi impostare immediatamente la sua affinità. IE: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8 Tuttavia, dopo aver letto il tuo commento e scoperto che Start-Processha un flag di affinità mancante, ho escogitato quanto segue, che ho testato: [System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010
Bewc,

Ti suggerisco di modificare la risposta per aggiungere quella alternativa.
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.