Zum Vorwort verwende ich Debian Wheezy mit Kernel 3.2 auf einem AMD64-Chipsatz. Meine Maschine hat zwei Xeon E5-2690-Kerne. Ich habe die Boot-Parameter so eingestellt, dass alle Kerne auf einer CPU einem einzigen Prozess zugeordnet sind. Dazu habe ich in grub isolcpus = 8,9,10,11,12,13,14,15 gesetzt.
So weit, ist es gut. Nehmen wir nun an, ich möchte die isolierten CPUs für einen bestimmten Befehl verwenden. Um einfach zu sein, verwende ich nur eine einfache Endlosschleife:
$ taskset -c 8-15 bash -c 'während true; hallo wiederholen> / dev / null; erledigt' &
So weit so gut, zeigt top, dass Core 8 sich bis zu nahezu 100% auslastet. Nehmen wir nun an, ich starte den Befehl erneut:
$ taskset -c 8-15 bash -c 'während true; hallo wiederholen> / dev / null; erledigt' &
Das obere Bild zeigt, dass die Kerne 9-15 inaktiv bleiben und die beiden Prozesse den Kern 8 gemeinsam nutzen. Wenn ich dies stattdessen tue:
$ taskset -c 8 Bash -c 'während true; hallo wiederholen> / dev / null; erledigt' &
$ taskset -c 9 bash -c 'while true; hallo wiederholen> / dev / null; erledigt' &
Die Kerne 8 und 9 werden jeweils zu 100% ausgelastet. Dies gilt nur für Isolcpus, da derselbe Tasksatz mit den Kernen 1-7 die Prozesse ordnungsgemäß auf die relevanten Kerne verteilt. Außerdem zeigt "taskset -p", dass die Affinitätsmaske für die 8-15-Prozesse korrekt eingestellt ist. Es sieht so aus, als ob der Kernel-Scheduler es ablehnt, irgendetwas anderes als den niedrigsten Kern zu verwenden, der auf einer Isolcpus-Affinitätsmaske angegeben ist.
Normalerweise würde das mit meinen obigen Beispielen keine große Rolle spielen, spezifizieren Sie einfach einzelne Kerne für jeden Prozess. Ich möchte jedoch eine Anwendung mit mehreren Threads auf der dedizierten CPU ausführen. Ich möchte den Kernsatz angeben und den Thread-Pool automatisch verwenden lassen, ohne die Prozessoraffinität für jeden einzelnen Thread, der erzeugt wird, einzeln zurücksetzen zu müssen.
Hat jemand eine Idee, wie man den Scheduler dazu bringt, mir mehr als einen Core aus dem Isolcpu-Set zu geben?
Antworten:
Nach einem Tag voller Frustration habe ich eine Lösung gefunden. Dieses Verhalten scheint ein Artefakt des Standard-Kernel-Scheduler-Algorithmus zu sein (SCHED_OTHER für diese Distribution / diesen Kernel). Durch die Umstellung des Prozesses auf einen anderen Algorithmus wird das Problem beseitigt. Isolationspuffer werden über die Prozesse / Threads hinweg in angemessener Weise verwendet.
Am Ende habe ich SCHED_RR verwendet, aber ich habe auch SCHED_FIFO und SCHED_IDLE getestet. Beide scheinen zu funktionieren. Der Prozess kann mit dem alternativen Algorithmus mithilfe des Dienstprogramms chrt gestartet werden:
$ sudo chrt -r 1 [Befehl]
(Wenn Sie als Nicht-Root-Benutzer ausgeführt werden möchten, können Sie das Dienstprogramm setcap verwenden, um CAP_SYS_NICE für die Binärdatei zu aktivieren, die sich auf den Befehl bezieht.)
quelle