8 Stimmen

Kann ich programmatisch auswählen, auf welchem Kern einer Multi-Core-CPU mein Thread laufen soll?

Oder wird sie vom Betriebssystem gesteuert? Ich habe gehört, dass die neue Go-Sprache von Google über eingebaute Funktionen verfügt, mit denen ein Programmierer so granular vorgehen kann, oder habe ich das falsch verstanden?

3voto

asveikau Punkte 37340

Sie wird durch das Betriebssystem bestimmt.

Sie können Hinweise dazu setzen mit pthread_attr_setaffinity_np() .

Aber das Betriebssystem kann Sie überstimmen. Der obige Aufruf ist nur ein Vorschlag, den Ihr Programm dem Betriebssystem macht.

Was Go anbelangt, so habe ich noch nicht damit gearbeitet und mich auch nicht zu sehr damit beschäftigt, aber nach meinem Verständnis von Go ist ein Großteil der Parallelität eher implizit. Sie haben Co-Routinen (sie sagen "Go-Routinen", sehr witzig) und Kommunikation zwischen ihnen. Es scheint, dass die CPU-Affinität und das Konzept des Threading selbst davon getrennt sind. Das heißt, die Laufzeit der Sprache könnte sogar entscheiden, alles auf einer CPU auszuführen, wenn sie das für das Beste hält... Aber auch hier gilt, dass ich mich nicht allzu sehr damit beschäftigt habe, ich könnte also falsch liegen :-)

3voto

Sam Liao Punkte 39747

Für Linux-Betriebssysteme, sched_setaffinity ist Ihre Antwort. Es wird seit Linux-Kernel 2.5.8 unterstützt.

Name

sched_setaffinity, sched_getaffinity - setzt und holt die CPU-Affinitätsmaske eines Prozesses

#define _GNU_SOURCE
#include <sched.h>

int sched_setaffinity(  pid_t pid,
    size_t cpusetsize,
    cpu_set_t *mask);

int sched_getaffinity(  pid_t pid,
    size_t cpusetsize,
    cpu_set_t *mask);

Die Affinitätsmaske ist eigentlich eine pro-Thread-Attribut, das unabhängig für jeden der Threads Threads in einer Thread-Gruppe angepasst werden kann. Der Wert der von einem Aufruf von gettid(2) zurückgegeben wird, kann im Argument pid übergeben werden. Die Angabe von pid als 0 setzt das Attribut für den aufrufenden Thread, und Übergabe des Wertes, der von einem Aufruf getpid(2) zurückgegebenen Wertes wird das Attribut für den Hauptthread des Threads Gruppe. (Wenn Sie die POSIX Threads-API verwenden, dann benutzen Sie pthread_setaffinity_np(3) anstelle von sched_setaffinity().)

3voto

poundifdef Punkte 17185

Die Antwort lautet: Ja, Sie können programmatisch auswählen, auf welchem Kern ein Prozess läuft. Wie arsane erwähnte, liegt die Antwort in sched_set_affinity() und dann pthread_setaffinity_np() für pthreads.

Hier ist ein raffiniertes Lernprogramm wie man das mit Prozessen macht (das stammt aus einer Antwort auf este Frage).

Dies geschieht im Wesentlichen mit einer Bitmaske. Das bedeutet, dass es eine ganze Zahl gibt (z.B. 32 Bits), und wenn das erste Bit == 1 ist, dann darf dieser Prozess auf Prozessor 1 laufen. Wenn das zweite Bit == 1 ist, dann darf dieser Prozess auf Prozessor 2 laufen. usw.

Standardmäßig ist also die Affinitäts-Bitmaske = 1...111 (32 mal). Das bedeutet: "Der Prozess kann auf Prozessor 1, 2, 3, ..., 32 laufen." Wenn Sie nur 2 Kerne haben, gelten die zusätzlichen 30 Bits natürlich nicht.

Wenn Sie diese Bitmaske jedoch auf 0...010 setzen, darf nur "Prozessor 2" diesen Prozess ausführen.

Das erklärt auch, warum die Höchstzahl der von Linux unterstützten Prozessoren ist 32. (out of the box, ohne Tweaking, x86, auf einem Großteil der gängigen Hardware, ohne Clustering, etc etc).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X