Suchen
Schließen Sie dieses Suchfeld.

Non-Uniform Memory Access (NUMA) Performance ist eine MESI-Situation

Geschrieben von:

„Nu mă, nu mă iei“
– Dan Mihai Bălan

Jeder, der schon einmal ein Linux-Dateisystem verwaltet hat, weiß vielleicht, dass ein Upgrade auf eine neue Version des Linux-Kernels normalerweise nicht allzu schwierig ist, aber manchmal kann es überraschende Auswirkungen auf die Leistung haben. Dies ist eine Geschichte aus einer dieser Zeiten.

Qumulo's Dateisystem-Software wird zusätzlich zu einer ziemlich standardmäßigen Ubuntu-Distribution ausgeliefert. Wir aktualisieren die Distribution und den zugrunde liegenden Linux-Kernel regelmäßig, um auf langfristig unterstützten Versionen zu bleiben, damit wir weiterhin über die neuesten Sicherheitsupdates und Fehlerbehebungen auf dem Laufenden bleiben und neuere Speichergeräte unterstützen können.

Wir haben vor kurzem alle unsere Plattformen aktualisiert, um Linux 5.4 zu verwenden – zuvor waren einige auf 4.4 und einige auf 4.15. Größtenteils lief alles reibungslos. Bei Leistungstests mit dem neuen Kernel ist uns jedoch etwas Merkwürdiges aufgefallen: Der Durchsatz für unsere 4U Dual Intel CPU Qumulo-Systeme (bei unseren Kunden als Qumulo QC104-, QC208-, QC260- und QC360-Systeme bekannt) war stark gesunken. In einem Test mit einer großen Anzahl von Schreibströmen ging der Durchsatz von ~4.5 GB/s auf etwa 3.2 GB/s zurück – ein Rückgang um fast 30 %!

Diese Systeme verwenden einen Dual-Prozessor von Haswell. Viele unserer Kunden haben große und aktive Bereitstellungen, auf die sie zur Verwaltung ihrer Daten angewiesen sind – und wir arbeiten konsequent daran, unsere Plattformen im Laufe der Zeit schneller und nicht langsamer zu machen!

Es war also an der Zeit, sich einzuarbeiten, herauszufinden, was unsere Software langsamer gemacht hat, und das Problem zu beheben.

Überwachung, Fehlerbehebung und Diagnose von Linux-Leistungsproblemen

Bei der Diagnose jeglicher Art von Leistungsproblemen beginnen wir normalerweise mit einem Blick auf Leistungsindikatoren, Latenzmessungen und andere Metriken, die durch die Instrumentierung in unserem Dateisystem generiert werden. Linux-Leistungsüberwachungstools wie diese ermöglichen es uns, leicht aufzuschlüsseln, wo das System seine Zeit verbringt, und die Ursache des Problems genauer zu diagnostizieren. In diesem Fall sagten die Metriken eine klare Geschichte: Festplatten-E/A war normal, CPU-Auslastung war normal, aber es wurde viel mehr Zeit für das Netzwerken aufgewendet.

Dies veranlasste uns, genauer nach Netzwerkinformationen zu suchen, die sich im Rahmen des Upgrades möglicherweise erheblich geändert haben. Glücklicherweise blieb uns das Durchforsten des Kernel-Codes erspart, da wir sofort einen Hauptverdächtigen fanden: Neben dem Upgrade auf Linux 5.4 hatten wir die Ethernet-Treiber geändert. Früher haben wir OFED für Mellanox-NICs verwendet, aber jetzt verwenden wir die im Kernel enthaltene Version.

Auch die Details des Treibercodes erwiesen sich als unwichtig, da die eigentliche Ursache für den Leistungsabfall eine kleine Konfigurationsänderung war: OFED enthält ein Skript, das Netzwerkinterrupts automatisch der nächstgelegenen CPU zuordnet, der In-Box-Treiber nicht. Die Wiedereinführung des Skripts oder die manuelle Einstellung der Affinitäten brachte sofort den gesamten Durchsatz zurück.

Wir hatten also unsere Antwort und mit einer kleinen Optimierung konnten wir die neue Distribution mit Kernel 5.4 getrost an unsere Kunden ausliefern.

Fehlerbehebung bei einem NUMA-bezogenen Leistungsengpass

Wir geben uns nicht damit zufrieden, nur Probleme beheben zu können. Wir wollen verstehen deren zugrunde liegende Ursachen. Und in diesem Fall schien etwas seltsam. In einem NUMA-System (Non-Uniform Memory Access System) ist es normalerweise besser, Interrupts lokal affiniert zu haben, aber bei den betrachteten Durchsatzniveaus (nur ein paar GB/s auf einem bestimmten Knoten) machte es keinen Sinn, dass die Kommunikation zwischen die CPUs könnten der Flaschenhals sein.

Das folgende Diagramm zeigt ein vereinfachtes Bild der Architektur. Es verfügt über zwei Xeon E5-2620 v3-CPUs, 128 GB RAM und eine Reihe von Festplatten:

 

Beachten Sie die Verknüpfungen zwischen den beiden CPUs. Dies sind QuickPath Interconnect (QPI)-Kanäle, die immer dann verwendet werden, wenn eine CPU Daten benötigt, die nur der anderen CPU zur Verfügung stehen – wenn beispielsweise CPU 1 Daten verarbeiten muss, die vom Netzwerk empfangen wurden, müssen die Daten QPI . überqueren .

[box type=“shadow“]Was ist QuickPath-Verbindung?

QuickPath Interconnect ist eine Datenverbindung zwischen einer CPU und anderen Motherboard-Ressourcen (z. B. einem IO-Hub oder anderen CPUs) in einigen Intel-Mikroarchitekturen, die erstmals 2008 eingeführt wurde. Ihr Ziel ist es, eine extrem hohe Bandbreite bereitzustellen, um später eine hohe On-Board-Skalierbarkeit zu ermöglichen Alles in allem macht es keinen Sinn, mehrere CPUs auf einem Motherboard unterzubringen, wenn diese die Systemressourcen nicht voll ausnutzen können. (Es wurde 2017 mit der Veröffentlichung der Skylake-Mikroarchitektur durch eine neue Version namens UltraPath Interconnect abgelöst.)[/box]

Der E5-2620 v3 verfügt über zwei 16-Bit-QuickPath-Interconnect-Kanäle getaktet mit 4GHz. Jeder Kanal überträgt Daten sowohl bei steigenden als auch bei fallenden Taktflanken, was zu 8 Gigatransfers (GT) pro Sekunde oder 16 GB/s Bandbreite in beide Richtungen führt. Mit zwei davon sollten wir also nahe an 32 GB/s kommen, bevor dieser Link zu einem Engpass wird – mehr als genug, um die relativ bescheidenen Anforderungen der NIC und der Speichergeräte zu bewältigen!

Es war jedoch klar, dass wir einen Engpass erlebten, der sich verschwand, als wir Maßnahmen zur Vermeidung der CPU-übergreifenden Kommunikation ergriffen haben. Was war also los?

Sehen wir uns an, was passieren muss, wenn ein Qumulo-Knoten eine Anfrage zum Lesen von Daten verarbeitet, beispielsweise mithilfe des NFS-Protokolls. Das folgende Diagramm zeigt eine vereinfachte Version des Datenflusses:

 

  1. Einige Daten müssen von anderen Knoten geholt werden (der blaue Pfeil). Diese Daten kommen als eine Reihe von TCP-Segmenten an der NIC an, die dann per DMA in Ringpuffer im Kernel und von dort in den internen Seitenpuffer des Qumulo-Dateisystems ausgelagert werden.
  2. Einige Daten werden von diesem Knoten geholt (lila Pfeil). Dieser wird von der Festplatte gelesen und in den Seitenpuffer kopiert.
  3. Sobald die lokalen Daten und die entfernten Daten gesammelt wurden, fügt ein Protokollarbeiter alles zu einer Antwort zusammen, die dann in Sendepuffer gelegt wird, von wo aus sie per DMA an die NIC übertragen und über das Netzwerk an den anfordernden Client gesendet werden .

Ins Zentrum der Zwiebel kommen

Eine wichtige Erkenntnis hierbei ist, dass jeder der Pfeile im obigen Flussdiagramm (mit Ausnahme derjenigen, die die NIC verlassen) einen Punkt darstellt, an dem es möglich wäre, dass Daten den QPI-Link manchmal mehr als einmal überqueren.

Erinnern Sie sich beispielsweise an das Architekturdiagramm, dass an beide CPUs Speichergeräte angeschlossen sind. Wenn CPU 0 1 GB Daten von einer an CPU 1 angeschlossenen Platte liest und sie dann in einen Bereich des Seitenpuffers kopiert, der dem an CPU 1 angeschlossenen Speicher zugeordnet ist, überqueren diese Daten die Verbindung zweimal. Der Protokoll-Worker, der die Daten verarbeitet, kann auf CPU 0 ausgeführt werden, sodass dieselben Daten die Verbindung erneut überqueren müssen und so weiter.

Es ist also ein „Verstärkungseffekt“ im Spiel – obwohl der Knoten möglicherweise nur Daten mit 2 GB/s bereitstellt, kann es sein, dass die QuickPath-Verbindung um ein Vielfaches so viel Datenverkehr trifft, da die gleichen Daten hin und her springen, wie z Data-Tennis-Spiel:

 

Identifizierung des wahren Schuldigen des NUMA-bezogenen Leistungsengpasses

Aber warte, ich höre dich sagen! Selbst in den pessimalsten Szenarien könnte diese Verstärkung 2 GB/s nicht in 32 GB/s verwandeln, es gibt einfach nicht genug Kanten, die die NUMA-Grenze in diesem Diagramm überschreiten!

Das stimmt – wir schienen vor einem Engpass weit unter der Nenngeschwindigkeit der Verbindung zu stehen. Glücklicherweise ist die Intel Speicherlatenzprüfung (auch bekannt als Intel MLC) kann die tatsächliche Leistung des Systems direkt messen, also haben wir es ausgeführt und es hat unsere Vermutungen bestätigt:

Measuring Memory Bandwidths between nodes within system
Bandwidths are in MB/sec (1 MB/sec = 1,000,000 Bytes/sec)
Using all the threads from each core if Hyper-threading is enabled
Using Read-only traffic type
            Numa node
Numa node        0         1
       0    46242.9          6291.7
       1     6276.3         46268.6</var/www/wordpress>

CPU 0 konnte mit ca. 46 GB/s auf den direkt angeschlossenen RAM zugreifen, und das Gleiche gilt für CPU 1 – aber sobald einer von ihnen auf den mit der anderen CPU verbundenen Speicher zugreifen wollte, waren mickrige 6 GB/s das Beste, was sie erreichen konnten .

Wenn Sie mit der Haswell-Architektur von Intel sehr vertraut sind, wissen Sie zu diesem Zeitpunkt möglicherweise bereits, was vor sich geht. Das war uns nicht besonders wichtig, also haben wir nach den Symptomen gegoogelt, und das hat uns zur richtigen Antwort geführt Intel-Community-Thread. Gehen Sie einfach ins BIOS, ändern Sie den „Snoop-Modus“ von „Early Snoop“ auf „Home Snoop“ und der Engpass verschwindet!

Also, was zum Teufel ist ein früher Schnüffler? Leider hat Early Snoop nichts damit zu tun, dass ein Cartoon-Beagle oder ein gewisser amerikanischer Rapper seine morgendliche Tasse Kaffee bekommt. Stattdessen müssen wir über eines der beiden schwierigsten Probleme der Informatik sprechen: Cache-Kohärenz. (Bei den anderen beiden handelt es sich um die Benennung von Dingen und um Einzelfehler.) Die Dinge werden bald MESI bekommen. Konkret ist Snooping Teil des MESI-Protokolls und damit auch der MESIF-Variante, die von Intel-Prozessoren verwendet wird.

Das MESI Cache Coherence Protocol

MESI ist ein gängiges Protokoll zur Durchsetzung der Cache-Kohärenz, das heißt, dass alle verschiedenen Caches im System eine konsistente Sicht auf den Speicherinhalt haben. MESI weist jeder Zeile in jedem Cache einen von vier Zuständen zu, der bestimmt, wie diese Cache-Zeile verwendet werden kann:

  • Geändert: Die Zeile wurde geändert und stimmt nicht mehr mit dem Inhalt im Hauptspeicher überein.
  • Exclusive: Die Zeile entspricht dem Hauptspeicher und ist nur in diesem Cache vorhanden.
  • Gemeinsam genutzt: Die Zeile ist unverändert, kann aber in anderen Caches vorhanden sein.
  • Ungültig: Die Zeile ist unbenutzt oder wurde ungültig gemacht (z. B. weil die Kopie eines anderen Caches geändert wurde).

MESI vs. MESIF

MESIF ist eine von Intel entwickelte Erweiterung von MESI. Es fügt einen fünften Zustand hinzu, F für „vorwärts“. Forward ähnelt Shared, jedoch darf nur ein Cache im System eine Zeile im Forward-Status haben. Dies ist hauptsächlich eine Optimierung, um übermäßige Antworten zu vermeiden, wenn eine Cache-Zeile vom System angefordert wird. Anstatt dass jeder Cache, der eine Kopie der Zeile enthält, antwortet, antwortet nur der Cache, der die Zeile im F-Zustand hält.

Sowohl in MESI als auch in MESIF werden die verschiedenen Caches durch Benachrichtigungen über den Bus kohärent gehalten, wenn wichtige Änderungen auftreten – wenn beispielsweise eine Zeile in einen Cache geschrieben wird, muss diese Kopie für jeden anderen Cache mit einer Kopie ungültig gemacht werden.

Früher Snoop vs. Home Snoop

Der Grund, warum diese Überlegung für die Leistung von entscheidender Bedeutung ist, hat mit der Anordnung der Caches in der Haswell-Architektur von Intel zu tun. Der gemeinsam genutzte Last-Level-Cache (LLC) auf jedem Paket ist in mehrere Slices unterteilt, eines pro Kern, die mit einem On-Die-Ring mit sehr hoher Bandbreite verbunden sind. Jeder Cache-Slice hat seinen eigenen Cache-„Agenten“. Für jeden Speichercontroller gibt es außerdem einen „Home-Agenten“:

 

Im „Early Snoop“-Modus (siehe oben, mit zwei CPUs) sendet der initiierende Cache-Agent eine Nachricht an alle anderen Cache-Agenten im System, wenn ein Cache-Miss oder ein Cache-Kohärenzereignis auftritt. Dadurch soll die Zugriffslatenz reduziert werden, indem die Zeit verkürzt wird, die zum Festlegen des Status einer Cache-Zeile erforderlich ist. Da jedoch alle Cache-Agenten auf der Remote-CPU über QuickPath Interconnect antworten, kann das Kohärenz-Chatter die verfügbare knotenübergreifende Speicherbandbreite erheblich reduzieren. Anscheinend reicht es beim Haswell-EP E5-2620 v3 aus, um 75 % Ihrer Bandbreite zu verlieren.

Im Gegensatz dazu werden im „Home-Snoop“-Modus Nachrichten zuerst von den Home-Agenten auf jedem Speichercontroller verarbeitet und dann nach Bedarf an LLC-Agenten delegiert. Der zusätzliche Hop führt zu einer geringen Latenz, hat aber den Vorteil eines deutlich höheren Durchsatzes. Beachten Sie, dass über QuickPath Interconnect weitaus weniger Nachrichten gesendet werden:

 

See Dieser Beitrag für eine tiefergehende Erklärung der NUMA-Cache-Kohärenz.

Wie viel besser ist Home Snoop?

Nachdem der Snoop-Modus auf allen Maschinen in unserem Testcluster geändert wurde, zeigte Memory Latency Checker einen deutlich verbesserten Durchsatz zwischen den CPUs:

Measuring Memory Bandwidths between nodes within system
Bandwidths are in MB/sec (1 MB/sec = 1,000,000 Bytes/sec)
Using all the threads from each core if Hyper-threading is enabled
Using Read-only traffic type
            Numa node
Numa node         0          1
       0     45139.0    25323.8
       1     25336.2    45021.7</var/www/wordpress>

Aber noch besser: Durch die Beseitigung dieses Engpasses wurde auch die Leistung dieser Systeme erheblich verbessert. Dadurch wurde nicht nur die 30-prozentige Regression beseitigt, die beim Verlust der Interrupt-Affinität beobachtet wurde, sondern es wurden noch weitere 30 % des zusätzlichen Durchsatzes hinzugefügt:

Test (4 Knoten, QC208) Grundlinie (frühes Schnüffeln) Heimschnüffler Change
Schreibdurchsatz 4400 MB/ 6000 MB/ + 36%
Lesedurchsatz 7650 MB / s 9550 MB/s/s + 29%

Ich erinnere mich an die erste Behebung von Leistungsproblemen auf dieser Plattform vor fünf oder sechs Jahren, sehr früh in meiner Karriere bei Qumulo – und ich kann mich dunkel daran erinnern, dass wir damals mit dem Snoop-Modus experimentiert haben. Damals machte es keinen großen Unterschied. Aber im Laufe der Jahre, als wir durch die Beseitigung von Software-Engpässen kontinuierlich Leistungsverbesserungen vornahmen, wurde die Leistung der zugrunde liegenden Hardwareplattform zum limitierenden Faktor, sodass die Erhöhung des QuickPath Interconnect-Durchsatzlimits zu einem großen Gewinn wurde.

Also, in der nächsten Version von Qumulo Corehaben wir Code hinzugefügt, um diese Einstellung im BIOS für alle betroffenen Modelle umzukehren, sodass alle unsere Kunden mit bestehenden Bereitstellungen von einer höheren Durchsatzkapazität profitieren würden.

Bei Qumulo wird noch viel mehr großartige Arbeit geleistet, um die Leistung unseres Dateisystems zu verbessern. Das meiste davon ist viel schwieriger (und sogar noch interessanter) als einen versteckten „Schnell gehen“-Schalter zu finden, also behalten Sie diesen Bereich im Auge!

Möchten Sie mehr über das Ingenieurwesen bei Qumulo erfahren? Weitere Beiträge von Qumulo-Ingenieuren anzeigen, hier. Alternativ schauen Sie sich die an Qumulo Data Platform – Übersicht über die Softwarearchitektur (PDF).


WEITERE LESUNG

Verwandte Artikel

Nach oben scrollen