Benchmark Methodik – Parameter und Testmethoden
Benchmarking als Mittelweg
Benchmarking ist schwierig, insbesondere wenn man nicht alle Aspekte vollständig unter Kontrolle hat (was für fast alles in der IT, Hardware oder Software gilt). Wir müssen also einen Mittelweg finden, wie unsere Tests reproduzierbare Ergebnisse liefern, die verstanden, interpretiert, gefiltert und kalibriert werden können, während die Komplexität unter Kontrolle bleibt.
Meistens ist es bequem, einfach ein „bekanntes Tool“ zu nutzen, welches eine einzelne Zahl (oder bestenfalls Min, Max und den Durchschnitt) als Ergebnis ausgibt – und fertig. Versteht mich nicht falsch: diese Zahlen können für einen sehr schnellen Vergleich nützlich sein … aber was bedeuten sie eigentlich? Und was nicht?
In diesem Artikel werden einige Aspekte erläutert, die ihr bei der Planung eines Benchmarks berücksichtigen solltet.
Allgemeine Überlegungen
Ein Benchmark wird normalerweise genutzt, um eine Software / Hardware / Infrastruktur mit einer anderen (Konfiguration) zu vergleichen. Hierbei die wichtigste Regel gleich vorweg: Vergleicht immer nur Äpfel mit Äpfeln.
Dies bedeutet nicht, dass Komponenten mit vielen verschiedenen Eigenschaften nicht verglichen werden können! Ihr müsst jedoch eure Tests für jede Komponente so kalibrieren, dass man die Ergebnisse später normalisieren, und sie unter gleichen Bedingungen vergleichen kann.
Erstellt am Besten eine Basismessung – die Baseline – als Anker für alle zusätzlichen Variationen bei der Testparametrisierung oder Konfigurationsänderungen. Obwohl man argumentieren könnte, dass die Baseline DIE wichtigste Messung ist, ist dies per Definition nicht so – es ist eher etwas, das:
- eine bekanntes und verstandenes Setup sowie Konfiguration verwendet
- leicht reproduzierbar ist
- keine hochspezifischen Optimierungen für Szenarien verwendet, die wir später testen wollen
Von der Baseline aus können wir dann die Variablen ändern und die Abweichungen messen. Auf diese Weise wissen wir viel besser, welche Änderung zu welcher Abweichung geführt hat.
Wenn ihr eure Ergebnisse erhalten habt, versucht, Ausreißer oder offensichtliche Caching-Effekte zu finden, und schließt sie nach Möglichkeit von euren Endergebnissen aus.
Messung der CPU-Raw-Computing-Leistung
Ihr wollt wissen, welche CPU insgesamt die beste Raw-Computing-Leistung aufweist (obwohl dies im Vergleich zu Tests unter realen Bedingungen möglicherweise etwas zu künstlich ist)?
Dafür müssen wir zuerst klären, wonach wir NICHT suchen, um die richtige Methodik auszuwählen (ein paar Beispiele):
- Preis/Leistung
- Effizienz (auch bekannt als Leistung / Stromverbrauch)
- die Leistung pro Kern
- die Leistung pro GHz
- Vielleicht sogar nicht die Leistung der Beschleunigungskomponenten wie AESNI, SSE, aber wenn sie verfügbar sind, sind sie möglicherweise trotzdem gut zu verwenden
- … wahrscheinlich noch viel mehr
Welche Probleme werden auftauchen, wenn wir diese Art von Test durchführen? Die rohe Rechenleistung ist äußerst schwer zu bestimmen, da viele Komponenten eine Rolle für die Ergebnisse spielen, wie z.B.:
- Beschleunigungskomponenten (jedes gute Tool und jeder Benchmark sollten CPU-Erweiterungen wie AESNI und SSE verwenden, falls verfügbar). Verwenden wir diese also oder eher nicht? Testen wir deren Einfluss/Beitrag separat?
- L1 / L2 / L3-Caches – sind sie kerngebunden oder was davon teilen sich mehrere Kerne? In welchem Maße? Wie groß sind die Caches jeweils? Wie würde ein Test diese Caches nutzen?
- Führt der Test Ganzzahl- oder Gleitkommaberechnungen durch? Oder geht es mehr um die Arbeitslast von Anwendungen? (Zum Beispiel Tests, die die Anzahl der Datenbanktransaktionen in einem Data Warehouse-Setup messen)
- Wie ist der Speicher mit den CPU Kernen verbunden? (Direkt, NUMA, Ringtopologie, Meshed, etc.)
- Sollten wir ein Benchmark-Tool an bestimmte Kerne anheften?
- Können wir den Benchmark mit allen verfügbaren Kernen gleichzeitig ausführen oder müssen wir aufgrund der Speicheranbindung aus einem Lauf auf einige Kerne extrapolieren? Kann das Ergebnis überhaupt extrapoliert werden?
Ihr habt es wahrscheinlich bereits erraten – die Verwendung eines „Benchmark-Tools zur Ermittlung der Rohleistung“ kann zu irreführenden Ergebnissen führen, wenn diese nicht richtig erzeugt und danach interpretiert / normalisiert werden.
Messung der Storage-Leistung
Jetzt möchten wir wissen, welches Blockspeichergerät oder welche -technologie ihr aufgrund ihrer IOPS auswählen solltet. Auch hier gibt es wieder viele verschiedene Aspekte die es zu berücksichtigen gilt.
Wollen wir wissen, wie viele IOPS ein Blockspeicher ausführen kann?
- pro Sekunde?
- im Peak?
- über einen langen Zeitraum?
- sequentielles, zufälliges oder gemischtes I/O-Muster?
- lesen, schreiben oder lesen-schreiben gemischt? Zu welchem Prozentsatz?
- Welche Bandbreite ist für unseren Fall interessant?
- Welche I/O-Latenz ist für unseren Fall interessant?
Eigentlich einfach, denn wir haben fio für all das, oder? Führt den Benchmark aus und verwendet diese Ergebnisse, um einen brutalen Vergleich durchzuführen. Aber was lernen wir eigentlich aus den Ergebnissen?
Beispiel
Während ich einige Speicherlatenz- und IOPS-Benchmarks mit FIO und einer Reihe von Persistant Memory Modules (PMM) durchführte, stellte ich durch Betrachtung des resultierenden Fio-Histogramms fest, dass die resultierende I/O-Latenzen sehr weit verteilt waren, wobei viele „zu gut, um wahr zu sein“ Ergebnisse auftauchten.
Sehr gut, geringe Latenz, Ergebnisse großartig… Perfekt, das wollten wir – Fall geschlossen. Oder nicht? Dies war ein klassischer Fall, in dem die endgültigen, aggregierten Benchmark-Ergebnisse etwas irreführend waren – zum Beispiel für 4k-Blockgrößen:
- Mindestlatenz: ~ 270 Nanosekunden
- durchschnittliche Latenz: ~ 1,2 Mikrosekunden
- mittlere Latenz: ~ 1,3 Mikrosekunden
Aber wenn man die einzelnen Messungen betrachtet und grafisch darstellt, sieht es so aus:
Die PMMs zeigten tatsächlich eine sehr gute Leistung innerhalb ihrer Spezifikation. Fast alle IOPS lagen im Bereich von etwa 1,2 bis 1,4 Mikrosekunden – ein beeindruckendes Ergebnis. Auf der linken Seite befinden sich jedoch einige Ausreißer im Bereich von 300 bis 400 Nanosekunden. Also, was ist hier los? CPU-Caches!
Die PMMs zeigten tatsächlich eine sehr gute Leistung innerhalb ihrer Spezifikation. Fast alle IOPS lagen im Bereich von etwa 1,2 bis 1,4 Mikrosekunden – ein beeindruckendes Ergebnis. Auf der linken Seite befinden sich jedoch einige Ausreißer im Bereich von 300 bis 400 Nanosekunden. Also, was ist hier los? CPU-Caches!
Einige der IOs konnten tatsächlich direkt aus dem Cache des CPU-Kerns bedient werden, auf dem der fio-Prozess ausgeführt wurde. Wir sprechen hierbei jedoch nicht über den Dateisystem-Cache oder ähnliches, sondern über das Caching innerhalb der CPU. PMMs die, identisch wie Hauptspeicher, direkt an die CPU angeschlossen sind, profitieren ebenfalls von diesen CPU-Level Cache-Effekten.
Immer gut zu wissen, was los ist. Nach dem Entfernen der Ausreißer stimmten die resultierenden Leistungsdaten perfekt mit den Erwartungen dieser PMMs und CPUs überein.
Schlussfolgerung
Nur in sehr wenigen Fällen möchten wir nur etwas sehr Spezifisches über die „rohe“ Leistung eines noch spezifischeren Aspekts von etwas wissen, an dem wir Benchmarks durchführen. Wir führen Benchmarks durch, um herauszufinden, wo unsere Anwendung oder unser Tool, welches wir verwenden möchten, höchstwahrscheinlich am besten ausgeführt werden kann.
Der beste Benchmark kann dann also etwas sein, das eine Arbeitsbelastung erzeugt, die der „realen Sache“ so nahe wie möglich kommt und gleichzeitig reproduzierbare Ergebnisse liefert.
Ein Blick auf das Preis- und Leistungsverhältnis kann auch den besten Rat geben, was zu wählen ist – am Ende ist die beste Leistung zum niedrigsten Preis das, wonach wir höchstwahrscheinlich suchen.
Die spezifischeren Benchmarks kommen dann ins Spiel, wenn die Benchmarks auf Anwendungsebene nicht eindeutig sind oder ihr Engpässe finden möchtet, die sonst nicht identifiziert werden können.