Wie kann man die Anzahl der CPU-Kerne einschränken, die jeder Benutzer verwenden kann?

17

Wir haben einen Computer mit 32 Kernen, auf dem einige Benutzer Programme ausführen können. Gibt es eine Möglichkeit, die Anzahl der Kerne zu beschränken, die jeder Benutzer zu einem bestimmten Zeitpunkt verwenden kann, damit ein Benutzer nicht die gesamte CPU-Leistung monopolisiert?

Reza
quelle
5
Keine Antwort, nur eine Idee. Möglicherweise möchten Sie mehrere virtuelle Maschinen einrichten. Jeder kann nur eine begrenzte Anzahl von CPUs haben. Jeder Benutzer würde sich nur auf einer der virtuellen Maschinen befinden, und die Benutzer auf dieser VM wären in der CPU-Auslastung beschränkt. Es kann sein, dass einige der Virtualisierungssoftware-Tools dies unterstützen.
Ghellquist
1
@ghellquist du solltest das beantworten
slebetman
@ghellquist: Sie möchten wahrscheinlich etwas so Leichtes wie möglich, wie Linux-Container, wenn Sie nur möchten, dass verschiedene Benutzer nur einige der CPUs sehen. (Wenn sie z. B. ein OpenMP- oder anderes Programm starten, das so viele Threads startet, wie es Kerne sieht, startet es eine geeignete Anzahl für die Anzahl der Kerne, die jeder Benutzer tatsächlich verwenden darf.) Eine vollständige Virtualisierung wie KVM hat auch bei Hardwareunterstützung wie VT-X oder AMD-V Leistungseinbußen durch zusätzliche Ebenen von Seitentabellen zur Folge, selbst wenn VM-Exits vermieden werden. Dies gilt für Code, bei dem TLB-Fehler auftreten, wenn viel Speicher berührt wird.
Peter Cordes
Es tut mir leid, aber besteht überhaupt ein Bedarf dafür? Als Mehrbenutzersystem implementiert Linux standardmäßig bereits präventives Multitasking. Daher sollte die Situation, in der ein einzelner (nicht böswilliger) Benutzer nur das gesamte System für sich beansprucht, nicht auftreten.
Cubic

Antworten:

16

Dies ist zwar möglich , aber kompliziert und mit ziemlicher Sicherheit eine schlechte Idee. Wenn zur Zeit nur ein Benutzer das Gerät verwendet, ist die Beschränkung auf N Kerne eine Verschwendung von Ressourcen. Ein weitaus besserer Ansatz wäre, alles zu betreiben mit nice:

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

Dies ist ein großartiges Tool, das die Priorität eines Prozesses festlegt. Wenn also nur ein Benutzer etwas ausführt, erhält er so viel CPU-Zeit, wie er benötigt. Wenn jedoch ein anderer Benutzer seinen eigenen (auch vernünftigen) Job startet, ist er nett und teilt ihn miteinander. Auf diese Weise wird, wenn alle Benutzer Befehle mit ausführen nice 10 command, niemand die Ressourcen belasten (und niemand wird den Server in die Knie zwingen).

Beachten Sie, dass ein hoher Nizza-Wert eine niedrige Priorität bedeutet. Dies ist ein Maß dafür, wie nett wir sein sollten und je schöner wir sind, desto mehr teilen wir.

Beachten Sie auch, dass dies nicht zur Verwaltung der Speicherzuordnung beiträgt, sondern nur die CPU-Planung beeinflusst. Wenn also mehrere Benutzer mehrere speicherintensive Prozesse starten, haben Sie immer noch ein Problem. Wenn dies ein Problem ist, sollten Sie sich mit geeigneten Warteschlangensystemen wie Drehmoment befassen .

terdon
quelle
Danke für deine Antwort. Es gibt einige "Workload-Manager" wie SLURM, diese sind jedoch für Computer mit mehreren Knoten gedacht. Ich denke, es ist sinnvoll, dass die Leute keine ähnlichen Apps für Einzelknoten-Computer entwickelt haben, da die Nachfrage nicht so groß ist.
Reza
@Reza versuch mal nice, was du beschreibst, das ist so ziemlich genau das, was du brauchst.
Terdon
3
@Reza: Das liegt daran, dass das Betriebssystem das bereits tut. Die verfügbaren CPUs werden bei Bedarf automatisch auf Threads / Prozesse aufgeteilt.
BlueRaja - Danny Pflughoeft
13

TL; DR : Aus kurzen Recherchen geht hervor, dass es möglich ist, Befehle auf eine bestimmte Anzahl von Kernen zu beschränken. In allen Fällen müssen Sie jedoch einen Befehl verwenden, der die Beschränkung tatsächlich erzwingt.

cgroups

Linux hat, cgroupswas häufig genau zum Zweck der Einschränkung der Ressourcen verwendet wird, die Prozessen zur Verfügung stehen. Nach einer kurzen Recherche finden Sie im Arch Wiki ein Beispiel mit der folgenden Matlab-Konfiguration (einer wissenschaftlichen Software) /etc/cgconfig.conf:

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

Damit eine solche Konfiguration wirksam wird, müssen Sie den Prozess über einen cgexecBefehl ausführen , z. B. von derselben Wiki-Seite aus:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

Task-Set

Eine verwandte Frage zu Ask Ubuntu und Wie beschränke ich einen Prozess auf einen CPU-Kern unter Linux? [duplicate] auf der Unix- und Linux-Site zeigt ein Beispiel für die Verwendung tasksetzur Beschränkung der CPUs für den Prozess. In der ersten Frage wird dies erreicht, indem alle Prozesse für einen bestimmten Benutzer analysiert werden

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

In der anderen Frage wird ein Prozess über sich tasksetselbst gestartet :

$ taskset -c 0 mycommand --option  # start a command with the given affinity

Fazit

Obwohl es durchaus möglich ist, Prozesse einzuschränken, scheint es nicht so einfach zu sein, dies für bestimmte Benutzer zu erreichen. Das Beispiel in einem verknüpften Ask Ubuntu-Beitrag erfordert ein konsistentes Scannen nach Prozessen, die jedem Benutzer gehören und tasksetfür jeden neuen verwendet werden. Ein weitaus vernünftigerer Ansatz wäre, CPU-intensive Anwendungen wahlweise über cgexecoder auszuführen taskset. Es ist auch nicht sinnvoll, alle Prozesse auf eine bestimmte Anzahl von CPUS zu beschränken, insbesondere für diejenigen, die Parallelität und Parallelität verwenden, um ihre Aufgaben schneller auszuführen. Wenn Sie sie auf eine bestimmte Anzahl von CPUs beschränken, kann dies die Verarbeitung verlangsamen. Darüber hinaus ist es, wie Terdons Antwort bereits sagte , eine Verschwendung von Ressourcen

Das Ausführen ausgewählter Anwendungen über tasksetoder cgexecerfordert die Kommunikation mit Ihren Benutzern, um ihnen mitzuteilen, welche Anwendungen sie ausführen können, oder das Erstellen von Wrapper-Skripten, mit denen ausgewählte Anwendungen über taskseloder gestartet werden cgexec.

Darüber hinaus sollten Sie die Anzahl der Prozesse festlegen, die ein Benutzer oder eine Gruppe erzeugen kann, anstatt die Anzahl der CPUs zu begrenzen. Dies kann über die /etc/security/limits.confDatei erreicht werden .

Siehe auch

Sergiy Kolodyazhnyy
quelle
1
Nun , es gibt cgrulesengd und cgrules.conf , um Prozesse automatisch in die entsprechende cgroup zu verschieben, basierend auf Benutzer / Gruppe, anstatt sich darauf zu verlassen, dass die Benutzer ihre Prozesse mit cgexec ausführen. Die Einrichtung in Ubuntu scheint jedoch nicht trivial zu sein.
Hans-Jakob
@ Hans-Jakob Es sieht etwas verworren aus und erfordert das Hinzufügen von Kernel-Flags in GRUB. Wahrscheinlich für Computer auf Unternehmensebene, auf denen Sie viele Benutzer haben und nicht möchten, dass diese das System zum Absturz bringen, ist dies wahrscheinlich sinnvoll, aber für den Desktop - zu viel Arbeit. Vielen Dank, dass Sie das verlinkt haben.
Sergiy Kolodyazhnyy
2
sched_setaffinity(2)sagt die Affinitätsmaske erhält across execve(2), und dass ein Kind erbt es auf fork(2). Wenn Sie also die Shell für einen Benutzer (oder die grafische Shell für eine X-Sitzung) festlegen, wird für alle, die von dieser Shell aus gestartet werden, standardmäßig dieselbe Affinitätsmaske verwendet.
Peter Cordes
1
Ein möglicher Nachteil sind Programme, die überprüfen, über wie viele CPUs der Computer verfügt, wenn Sie festlegen, wie viele Threads gestartet werden sollen. Sie haben zu viele Threads für die Anzahl der Kerne, auf denen sie tatsächlich geplant werden. Haben Sie herausgefunden, ob cgroups etwas dagegen unternehmen könnte?
Peter Cordes
@PeterCordes Laich-Shell-Idee klingt interessant. Ich muss das untersuchen. Vielen Dank ! Was den zweiten Kommentar betrifft, nein, ich habe zu diesem Zeitpunkt noch nicht genug über Gruppen recherchiert.
Sergiy Kolodyazhnyy