Frage

Ich betreiben massiv parallele wissenschaftliche Rechenjobs auf einen gemeinsam genutzten Linux-Computer mit 24 Cores. Die meiste Zeit sind meine Jobs fähig ist zu 24 Kerne skaliert, wenn nichts anderes auf diesem Computer ausgeführt wird. Es scheint jedoch, wie wenn auch nur ein Single-Threaded-Job, der ist nicht von ich laufe, meine 24-Thread-Arbeitsplätze (die mich für hohen schönen Wert) verwalten nur ~ 1800% CPU zu erhalten (unter Verwendung von Linux-Notation). Inzwischen etwa 500% der CPU-Zyklen sind (wieder mit Linux-Notation) im Leerlauf. Kann jemand dieses Verhalten erklären und was ich dagegen tun kann, um alle 23 Kerne zu erhalten, die nicht von jemand anderem verwendet werden?

Weitere Informationen:

  1. Falls es relevant ist, ich habe diese Versionen auf etwas anderen Kernel beobachtet, obwohl ich das aus der Spitze von meinem Kopf nicht mehr erinnern kann.

  2. Die CPU-Architektur ist x64. Ist es überhaupt möglich, dass die Tatsache, dass meine 24-Core-Arbeitsplätze sind 32-Bit und die anderen Jobs, die ich bin im Wettbewerb w / sind 64-Bit ist relevant?

Edit: Eine Sache, die ich ist gerade bemerkt, dass bis zu 30 Threads steigen scheint das Problem zu einem gewissen Grad zu lindern. Es wird mir zu ~ 2100% CPU auf.

War es hilfreich?

Lösung

Es ist möglich, dass dies durch den Scheduler verursacht wird versucht, jede Ihrer Aufgaben auf der gleichen CPU laufen zu halten, dass sie vorher auf ausgeführt wurde (es ist dies, weil die Aufgabe wahrscheinlich seine Arbeitssatz in das CPU-Cache gebracht hat - es ist "Cache-hot").

Hier ein paar Ideen können Sie versuchen:

  • Ausführen doppelt so viele Threads wie Sie Kerne haben;
  • Ausführen ein oder zwei weniger Threads als Sie Kerne haben;
  • Reduzieren Sie den Wert von /proc/sys/kernel/sched_migration_cost (vielleicht bis auf Null);
  • Reduzieren Sie den Wert von /proc/sys/kernel/sched_domain/.../imbalance_pct nach unten näher an 100.

Andere Tipps

Sie Ihre Threads synchronisieren? Wenn ja, könnten Sie folgendes Problem:

Angenommen, Sie haben ein 4-CPU-System, und einen 4-Faden-Job. Wenn allein laufen, Gewinde auffächern zu verwenden, um alle 4 Kerne und Gesamtverbrauch ist nahezu perfekt (Wir werden diese 400% nennen).

Wenn Sie eine Single-Thread-interferierende Job hinzufügen, kann der Scheduler Platz 2 der Threads auf der gleichen CPU. Dies bedeutet, dass 2 der Threads sind jetzt bei effektiv die Hälfte ihrer normalen Tempo (dramatische Vereinfachung) ausgeführt wird, und wenn Sie Ihre Threads regelmäßig synchronisieren müssen, kann der Fortschritt Ihrer Arbeit durch den langsamsten Thread begrenzt werden, was in diesem Fall läuft an Hälfte der normalen Geschwindigkeit. Sie würden Auslastung von nur 200% sehen (von Ihrem Job läuft 4x 50%) plus 100% (der störenden Job) = 300%.

Und falls Sie davon ausgehen, dass der störende Job verwendet nur 25% eines Prozessors Zeit ist, kann eines der Threads und die Störer auf der gleichen CPU sehen. In diesem Fall läuft der langsamste Faden bei 3/4 der normalen Geschwindigkeit, so dass die Gesamtauslastung 300% (4 x 75%) + 25% = 325% liegt. Spielen Sie mit diesen Zahlen und es ist nicht schwer zu kommen mit etwas Ähnliches, was Sie sehen.

Wenn das ist das Problem, werden Sie sicherlich mit Prioritäten spielen können unliebsame Aufgaben nur winzige Bruchteile der verfügbaren CPU zu geben (Ich gehe davon aus E / A-Verzögerungen sind kein Faktor). Oder, wie Sie gefunden haben, versuchen Sie Threads zu erhöhen, so dass jede CPU hat, sagen wir, zwei Fäden, minus ein paar für Systemaufgaben zu ermöglichen. Auf diese Weise wird ein 24-Core-System könnte am besten mit laufen, sagen wir, 46 Threads (was immer verlässt die Hälfte der 2 Kerne Zeit für Systemaufgaben zur Verfügung).

Haben Ihre Fäden miteinander in Verbindung stehen?

Versuchen

manuell binden jeden Thread zu cpu, mit sched_setaffinity oder pthread_setaffinity_np. Scheduler kann ziemlich dumm sein, wenn mit viel Bezug Threads arbeiten.

Es könnte sich lohnen zu verwenden mpstat (Teil des sysstat Paket) zu Figur aus, wenn Sie ganze CPUs haben untätig, während andere voll ausgenutzt werden. Es sollte Ihnen eine detailliertere Ansicht der Nutzung als oben geben oder vmstat:. Laufen mpstat -P ALL 1 Zeile pro CPU sehen

Als ein Experiment, könnten Sie versuchen, die CPU-Affinität Einstellung auf jedem Thread, so dass jeder auf eine einzelne CPU gebunden ist; dies würde Sie sehen, was die Leistung wie, wenn Sie nicht lassen Sie sich entscheiden, der Kernel-Scheduler die CPU eine Aufgabe geplant ist. Es ist keine gute dauerhafte Lösung, aber wenn es hilft viel es gibt Ihnen eine Vorstellung davon, wo der Planer fällt kurz.

Denken Sie, der Engpass in der Anwendung oder der Scheduling-Algorithmus des Kernels? Bevor Sie Planungsparameter starten zwicken, schlage ich vor Sie versuchen, eine einfache Multi-Threaded-Anwendung ausgeführt wird, um zu sehen, ob es das gleiche Verhalten wie Ihre Anwendung zeigt.

// COMPILE WITH: gcc threads.c -lpthread -o thread
#include <pthread.h>
#define NUM_CORES 24

void* loop_forever(void* argument) {
    int a;
    while(1) a++;
}

void main() {
    int i;
    pthread_t threads[NUM_CORES];

    for (i = 0; i < NUM_CORES; i++)
        pthread_create(&threads[i], 0, loop_forever, 0);

    for (i = 0; i < NUM_CORES; i++)
        pthread_join(threads[i], 0);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top