Wie beschränke ich einen Prozess auf einen einzelnen CPU-Kern?

30

Wie können Sie ein einzelnes Prozessprogramm, das in einer Windows-Umgebung ausgeführt wird, so beschränken, dass es nur auf einer einzelnen CPU auf einem Multi-Core-Computer ausgeführt wird?

Ist es dasselbe zwischen einem Fensterprogramm und einem Befehlszeilenprogramm?

AKTUALISIEREN:

  • Grund dafür: Benchmarking verschiedener Aspekte der Programmiersprachen
  • Ich brauche etwas, das von Anfang an funktionieren würde, daher löst @ akselis Antwort meinen Fall nicht, obwohl sie für andere Fälle gut ist
Jonathan
quelle
2
Warum willst du das machen? Das Betriebssystem entscheiden zu lassen, welche CPU / welcher Core welchen Prozess ausführt, wird wesentlich effizienter.
ChrisF
1
um verschiedene Aspekte der Programmiersprache zu vergleichen
Jonathan
1
Das ist ein guter Grund - Sie sollten diese Informationen in Ihre Frage aufgenommen haben. Es ist wichtig.
ChrisF
Motivation ist nicht wesentlich, aber ich fügte es Ihrem Rat hinzu
Jonathan
1
Dies können jedoch die Informationen sein, die jemand benötigen muss, um eine Antwort zu geben.
ChrisF

Antworten:

27

Wenn Sie Windows Vista / 7 verwenden (möglicherweise XP, aber nicht sicher), ist dies recht einfach.

Tippe ein: Control+Shift+Escum deinen Taskmanager aufzurufen.

Klicken Sie auf die Registerkarte Prozesse

Suchen Sie den Prozess, dessen Prozessoraffinität geändert werden muss

Klicken Sie mit der rechten Maustaste auf den Prozess

Klicken Sie auf "Set Affinity"

Hier können Sie auswählen, welche Prozessoren Ihr Prozess verwenden soll.

Viel Glück!

EDIT: Sie müssen Administrator sein, damit dies funktioniert.

akseli
quelle
13
Eine Affinität ist keine Garantie. Die Prozesse bevorzugen diesen Prozessor, aber wenn er mehrere Threads enthält, bleiben nicht alle dort.
Joel Coehoorn
1
Das ist gut, aber ich brauche etwas, das von Anfang
Jonathan
2
@ JoelCoehoorn: Nein, es ist eine Garantie. Sie sprechen von dem bevorzugten Prozessorvektor, der sich vom Affinitätsvektor unterscheidet.
Mehrdad
1
@Mehrdad: es sei denn, das Programm selbst ändert es nach Belieben.
Eugene Ryabtsev
1
@JoelCoehoorn > Thread-Affinität zwingt einen Thread, auf einer bestimmten Teilmenge von Prozessoren ausgeführt zu werden. - Sie scheinen sich auf einen Thread-idealen Prozessor zu beziehen .
Bob
19

Verwenden Sie in der Befehlszeile

start / affinity 1 program.exe

Dadurch wird program.exe auf der ersten CPU ausgeführt, da "1" der Hex-Wert der Affinitätsmaske ist

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 

quelle
1
Revolter: Weißt du, ob ich dasselbe mit der Initialisierung von Diensten machen kann?
Diogo
Was ist, wenn Sie mehr als 4 Kerne haben?
posfan12
7

Kommt darauf an, wozu Sie bereit sind:

Methode 1: Auf Anfrage

Verwenden Sie ImageCFG . Mit diesem Dienstprogramm können Sie eine ausführbare Datei so einrichten, dass sie auf einer beliebigen Anzahl von Kernen ausgeführt werden kann. Stellen Sie sicher, dass Sie eine Sicherungskopie der ausführbaren Datei Ihres Ziels erstellen, bevor Sie die Änderungen vornehmen, und stellen Sie sie wieder her, wenn Sie mit dem Spiel fertig sind.

Methode 2: Erzwingen einer gesamten Windows-Sitzung (Vista / 7)

  1. Geben Sie bcdedit /set onecpu onan einer Eingabeaufforderung ein
  2. Starten Sie das System neu.
  3. Wenn Sie fertig sind, geben Sie 2 - Type: ein bcdedit /set onecpu offund starten Sie erneut.

Methode 2: erzwingen Sie eine gesamte Windows-Sitzung (XP)

  1. Öffnen Sie Ihre boot.ini-Datei (Klicken Sie mit der rechten Maustaste auf Arbeitsplatz -> Eigenschaften -> Registerkarte Erweitert -> Schaltfläche Einstellungen unter 'Starten und Wiederherstellen' -> Schaltfläche Bearbeiten unter 'Systemstart').
  2. Sie finden den folgenden (oder einen ähnlichen) Abschnitt in der Datei:

    [Betriebssysteme]

    Multi (0) -Disk (0) -Rdisk (0) -Partition (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect

  3. Ändern Sie es, indem Sie das Flag / onecpu hinzufügen:

    [Betriebssysteme]

    Multi (0) -Disk (0) -Rdisk (0) -Partition (2) \ WINDOWS = "Microsoft Windows XP Professional" / fastdetect / onecpu

  4. Starten Sie neu. Wenn Sie fertig sind, entfernen Sie die Markierung und starten Sie erneut.

Methode 0: Keine gute Methode (Prozessoraffinität)

Alles, was sonst die Prozessoraffinität betrifft, ist leider keine gute Option. Die Prozessoraffinität ist ein Hinweis auf den Prozessor. Der Verarbeiter ist nicht verpflichtet, dies zu respektieren, und wird dies häufig auch nicht tun.

Ein Zwerg
quelle
Methode 2 scheint auf Win7 nicht zu funktionieren. D:\>bcdedit /set onecpuErgebnisse in The set command specified is not valid....The parameter is incorrect.
max
2
technet.microsoft.com/en-us/library/cc938636.aspx sagt "... hard affinity", was bedeutet, dass die Prozessoraffinitätsmaske die von der Affinitätsmaske betroffenen Threads auf die von der Maske angegebenen Prozessoren beschränkt "Affinitätsmaske läuft nicht auf Prozessoren, die nicht in der Affinitätsmaske enthalten sind". Gibt es eine Quelle, die sagt, dass sie nicht respektiert wird?
Eugene Ryabtsev
4

Ich habe die folgende Funktion in mein Programm in Python 2.6 eingefügt und es ruft Windows-Funktionen auf. Meine Maschine hat nur zwei Kerne, so dass Sie diesen Teil möglicherweise ändern müssen. In den Kommentaren erfahren Sie, wie die aktuelle Affinität lautet. Es funktioniert "so wie es ist" für einen Single-Core-Rechner, wenn Sie eine Maske von 1 festlegen oder als Standard festlegen.

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
quelle
Ich
bin
Wie führt man diese Funktion von der Kommandozeile oder der Batch-Datei aus? Gibt es eine Möglichkeit, die Prozess-ID im Voraus zu kennen oder festzulegen?
posfan12
4

Auf der Suche nach sehr ähnlichen Informationen mithilfe von PowerShell habe ich die erforderlichen Informationen hier gefunden: http://www.energizedtech.com/2010/07/powershell-setting-processor-a.html

Sie haben nicht erwähnt, welches Windows-Betriebssystem Sie verwenden. (Die älteren Betriebssysteme wurden nicht mit PowerShell geliefert. Sie können es jedoch installieren, wenn es nicht vorhanden ist.)

Das Wichtigste dabei ist, dass in PowerShell die Prozessaffinität einfach eine Eigenschaft ist, die Sie leicht ändern können.

Der PowerShell-Befehl zum Anzeigen der Eigenschaften (und anderer Informationen) Ihres Prozesses (am Beispiel von foo) lautet:

Get-Process foo | Get-Member

Sie werden sehen, ProcessorAffinity ist eine dieser Eigenschaften. Das Ändern ist trivial, und Sie können auswählen, auf welchem ​​Core Sie ausgeführt werden möchten, indem Sie die Werte aus der obigen Tabelle / dem obigen Link von Revolter verwenden.

Mit dem folgenden Befehl können Sie feststellen, welchen Wert die ProcessorAffinity-Eigenschaft für foo hat:

(Get-Process foo) .ProcessorAffinity

Wenn Sie also foo nur auf CPU 4 ausführen möchten, legen Sie den Wert so fest:

(Get-Process foo) .ProcessorAffinity = 8

Bewc
quelle
Ich kann Ihrer Erklärung nicht entnehmen: Gilt dies nur für bestehende Prozesse? Das OP möchte keinen Prozess starten und dann seine Affinität festlegen. Er möchte einen Prozess starten, dessen Affinität bereits festgelegt ist , wie in der start /affinityAntwort. Kann deine Technik das? Wenn ja, erläutern Sie bitte, wie.
Scott
2
@Scott Nur vorhandene Prozesse. In dem von Ihnen angegebenen Kontext hilft meine Antwort nicht weiter. Ich hatte das Gefühl, dass der "Anfang des Prozesses" eine Frage des Beginns des Prozesses und der sofortigen Einstellung seiner Affinität war. IE: Start-Process foo ; (Get-Process foo).ProcessorAffinity=8 Nachdem ich Ihren Kommentar gelesen und festgestellt habe, dass Start-Processeine Affinitätsflagge fehlt, habe ich Folgendes gefunden, das ich getestet habe: [System.Diagnostics.Process]::start("foo.exe").ProcessorAffinity=0x0010
Bewc
Ich schlage vor, dass Sie Ihre Antwort bearbeiten, um diese Alternative hinzuzufügen.
Scott