Jahresumfrage: SIMD in Rust ist ausgereift, std::simd bleibt Nightly
Sergey "Shnatsel" Davidoff hat seine zweite jährliche Bestandsaufnahme zur SIMD-Programmierung in Rust veröffentlicht. Der Kern: Das Ökosystem ist erwachsen geworden. Neue Compilerfunktionen und Bibliotheken machen Rust für vektorisierten Code attraktiv, auch wenn Speichersicherheit gar nicht der Grund für die Sprachwahl ist. Davidoff betreut inzwischen selbst eine der besprochenen Bibliotheken, fearless_simd, und legt das offen. Um den Interessenkonflikt auszugleichen, hat er den Entwurf den Autoren von std::simd, wide, pulp und macerator vorgelegt, die redaktionelle Hoheit aber behalten.
Den größten Fortschritt tragen drei Sprachänderungen. Seit Rust 1.87 darf eine mit #[target_feature(enable = "avx2")] markierte Funktion Plattform-Intrinsics ohne unsafe-Block aufrufen; Lade- und Speicheroperationen über Rohzeiger brauchen ihn weiterhin, was Bibliotheken mit bereichsgeprüften Hüllen lösen, die der Optimierer anschließend wieder entfernt. Rust 1.98 hat "algebraische" Gleitkommaoperationen wie algebraic_add() stabilisiert: Damit darf der Compiler Rechenschritte umordnen und Summen automatisch vektorisieren, die bisher skalar bleiben mussten. Und das portable std::simd der Standardbibliothek bleibt der Baustein, auf den alle warten - es läuft aber weiterhin nur auf Nightly und bekommt gelegentlich inkompatible Änderungen.
Mit Grenzen geht der Text offen um. std::simd setzt direkt auf LLVM auf und erreicht damit jede Zielplattform von LLVM; fehlt dort aber die passende Operation, entsteht stillschweigend skalarer Code - sin() und reduce_sum() werden ausdrücklich genannt. Die Crate multiversion kostet pro Aufruf weniger als ein Dutzend Befehle, was nur bei sehr kleinen Funktionen ins Gewicht fällt. Crates, die überwiegend von KI entwickelt werden, schließt Davidoff aus seinen Empfehlungen aus, zwei davon wegen nachweisbarer Fehler.

Was das bedeutet
Am nützlichsten ist der Abschnitt über Intrinsics, weil er für C und C++ genauso gilt wie für Rust. Davidoff beschreibt einen ARM-Ladebefehl, den der Compiler als Blackbox behandelte, sodass eine Konstante zweimal über den Stack wanderte; eine LLVM-"Optimierung", die einen 512-Bit-Shuffle durch langsameren Code aus der SSE4.2-Zeit ersetzte und nach seinem Bericht in LLVM 23 behoben ist; und eine Liste noch offener LLVM-Fehler. Die Lehre: Ein Intrinsic garantiert nicht den Befehl, den man bestellt hat.
Zwei praktische Folgen. Wer Binärdateien verteilt, braucht Auswahl zur Laufzeit - der Text zitiert Steams Hardwaredaten mit 23,9 Prozent Systemen mit AVX-512, das feste Kompilieren für eine moderne CPU ist also nur auf der eigenen Flotte sicher. Und wer Trigonometrie auf Gleitkommavektoren braucht, sollte den erzeugten Assemblercode prüfen, bevor er einer Bibliothek vertraut: Die beste Option, die der Autor gefunden hat, ist nach eigener Aussage eine unvollständige Portierung, die noch leicht fehlerhaft ist.