CI Performance - netcup Runner vs. WarpBuild

Für eine bessere Entscheidungsfindung müssen Messungen auf dem netcup RS 8000 G12 (Windows) gegen die bestehenden WarpBuild Runner gemacht werden.

Roh-Metriken

MessungnetcupWarpBuildGithub/Azure
7z b -mmt14346 MIPS6891 MIPS5104 MIPS
(Compressing)2874 MIPS5851 MIPS3990
Taktung3.1 GHz3.69 GHz2.9 GHz
BDD-Assembly (16k Tests)42m24m10s1h3m
Checkout cmi-metatool (full)60s~60s~60s

Performanceoptimierung über Warp

In diesen Tests wurde ein enormes Bottleneck entdeckt.
Die Schultests blockieren den kompletten Arbeitsspeicher, auch wenn Sie nur 25% der Tests ausmachen.
Nach dem Sharding auf GitHub (Schule / Rest, zwei Runner) entstehen folgende Metriken:

KonfigurationLaufzeit
1x 8x, ungeshardet (alt)24m10s
2x 4x, Schule-Split (neu)16m06s
2x 8x, Schule-Split13m20s

Die 2x 4x Variante ist etwa gleich teuer wie heute, dabei alleridngs 33% schneller.
Aus diesem Grund wurde mit diesem PR die Umstellung auf 2x4x gesetzt,
wodurch die effektive Wartezeit um 10 Minuten reduziert werden konnte.

Grundlegene Probleme

Während im Linux Bereich auf Netcup Alles mehr als genügend ist,
kristallisiert sich auf Windows (und damit für CMInformatik/cmi-metatool) ein Problem heraus.
Die Root-Server von netcup sind leider nicht metal sondern quasi eine VPS mit dedizierten Kernen.
Daraus ergibt sich zum einen der leider immer noch enorme Performance Overhead durch die CPU virtualisierung, zum Andern aber das Hauptproblem, mit dem wir vor Allem in den BDD Tests kämpfen müssen:

Memory-Bandbreite

Sharding auf 3 Prozesse hob die CPU-Last von 27% auf 90%, der Durchsatz fiel aber um ein Drittel (39 min -> 58m24s).
Parallelisierung hilft dort nicht, sie schadet.
Während die Infrastruktur immer noch weit besser dasteht, als ihr Pendant auf Github (also Azure),
läuft auf den Warp Instanzen Gaming Hardware, die gerade in diese Bandbreiten gebundenen Szenarien ihre konkurrenz zerstört.

Kein git filter

filter: blob:none würde den checkout von 900MiB auf knapp 380MiB reduzieren.
Da wir hier allerdings Nerdbank für die Versionierung verwenden, kann das nicht gverwendet werden:

Unable to get version from commit

Dies erklärt auch den revert in cmi-metatool#9723 aus 2024.

Azure Disk der Forgejo-Instanz

Gemäss cmi-prod-infrastructure bekam die Forgejo Instanz eine PremiumV2_LRS mit 3000 IOPS (250 MB/s)
und cachingMode: None für bessere Performance.
Im realen Gebrauch (also random IOPS) zeichnet sich ein düsteres Bild ab

  • Artifact-Upload (1.9 GB): 55s = 34.5 MB/s,
    also gerade einmal ein Siebtel der angegebenen Bandbreite.
    Uploads erfolgen in 8MiB grossen Chunks mit ca. 200ms Overhead.
  • 5 parallele Downloads: je ~30 MB/s.

Um das zu mitigieren, müsste zumindest für die Artefakte ein S3 mittels silo auf einem der Runner gehostet werden.

Kosten fuer echte dedizierte Hardware

Ein Hetzner AX102-1 für 259€ /Mo (+ 129€ einmalig) liefert:

  • CPU: AMD Ryzen 9 7950X3D, 16C/32T,
  • RAM: 128 GB DDR5
  • Disk: 2x 1.92 TB NVMe.
AnzahlEUR/MonatSetup einmalig
2 Maschinen518.00258
3 Maschinen777.00387
4 Maschinen1036.00516

Drei Maschinen sind die Empfehlung: Peak-Parallelitaet einer vollen Pipeline sind 8 Windows-Jobs, der Gesamtverbrauch liegt aber nur bei ~122 Runner-Stunden im Monat. Die 10-Gbit-Option (43 EUR) ist unnoetig und halbiert ausserdem das Freivolumen.

Züricher Pendant

Evoluso (Zürich, echtes Bare Metal):

ModellCPURAMDiskEUR/Monat
CH-1Ryzen 9 7900, 12C/24T (bis 5.4 GHz)32 GB DDR51 TB NVMe199
CH-2EPYC 7282 Rome, 16C64 GB DDR41 TB NVMe219
CH-3EPYC 7443P Milan, 24C128 GB DDR42 TB NVMe299

Nur CH-1 kommt in Frage: die beiden EPYC-Varianten sind Zen 2 bzw. Zen 3 mit niedrigem Takt und würden sich vermutlich ähnlich verhalten wie netcup. CH-1 hat dafür nur 32 GB RAM - bei 8-10 GB pro BDD-Shard reicht das für zwei Shards damit leider nicht mehr.

Hinzu kommt dann aber noch ein Performance Impact! Auf Notebookcheck bemerkt man die deutlich geringere Taktung und den L3 Cache.

Evoluso CH-1 ist trotz des niedrigeren Preises dennoch die schlechtere Wahl:

  • 12 statt 16 Kerne
  • 5.4 statt 5.7 GHz Boost
  • nur 64MB L3 statt 128MB

Beim 7950X3D sitzt der 3D V-Cache auf einem der beiden CCDs, das sieht also 96 MB gegenüber 32 MB pro CCD des Ryzen 7900.
Für einen cache-gebundenen Prozess also der Faktor 3.
Genau hier ist aber unser Flaschenhals

  • 46% Rueckstand beim Compressing
  • nur 10% beim Decompressing.
  • Dazu 32 GB RAM statt 128 GB
  • (erwähenswert) nur 1 TB statt 3.8 TB NVMe.

Preisvergleich für vergleichbare Leistung:

CPURAMDiskEUR/Monat
Hetzner AX102-1 (DE)7950X3D, 16C/32T128 GB2x 1.92 TB259
Evoluso CH-1 (CH)7900, 12C/24T32 GB1 TB199

Offene Fragen (erst nach Test)

Leistung nur extrapoliert

Die AX102-Leistung ist nicht gemessen, aber kann gut extrapoliert werden. Der EPYC 9R14, der in Warp verwendet wird, und Hetzners 7950X3D sind beide Zen 4 und ihre threads skalieren mit dem Takt. Aus unserer eigenen Messung (6891 MIPS @ 3.69 GHz = 1867 MIPS/GHz) ergeben sich bei 5.7 GHz rund 10.600 MIPS.
Unter Linux mit einem Ryzen 7900X3D erreiche ich sogar 11.248 MIPS, obwohl dieser gemäss GeekBench 5 um 1,9% langsamer sein soll.
Dieser Prozessor ist allerdings der kleien Bruder (4 physische Kerne weniger).
Da wir bereits Parallelisierung komplett widerlegt haben, können diese Werte als identisch betrachtet werden.

Ich erwarte daher rund 1.3 - 1.35x die Leistung von Warp pro Thread. Wichtig: der Linux-Build von 7-Zip ist auf identischer Hardware ~23% schneller als der Windows-Build (gemssen in netcup: 5342 vs 4346 MIPS),
die 11248 MIPS dse7900X3D könnten unter Windows also gerne nur 9200 sein.

MessungWarp heuteAX102 erwartet
Schule-Shard11m30s~8m30s
Rest-Shard8m35s~6m20s
BDD-Stage13m20s (2x 8x)~9-10 min (1 Maschine)
ci_build (MSBuild)6m22s (1x 16x)3m

Eine einzelne Maschine würde damit leisten, wofür heute zwei Warp-8x gebraucht werden.
Der Vorbehalt bleibt die Speicherbandbreite: zwei Shards auf einer Maschine teilen sich ~58 GB/s (Dual-Channel DDR5-3600).
Im Verlgeich hat ein EPYC-Socket zwölf Kanäle.
Falls das kracht, ergibt sich dasselbe Muster wie bei netcup: CPU-Last steigt, aber Durchsatz fällt.
Mitigation wäre ein Shard pro Maschine, womit wir immer noch deutlich günstiger unterwegs wären als in der bisherigen Strategie.

Da wir hier aber einen Gamingprozessor haben, muss hier nicht so viel geraten werden. Meine Vermutung ist, dass da 4x32G DDR5-3600 drinstecken.

Problemkind Azure PremiumSSD

Die Azure Disk ist in ihrer Performance immer noch unter aller Kanone.
Wenn das Ding tatsächlich nur 35MB/s liefert, dann quält das unsere Entwickler und das ganze Unterfangen ist nicht mehr tragbar. Denn dann würden sich Entwickler, Workflows und CLaude um die Bandbreite der Disk schlagen.