====== Lyx – Energy-Aware Programmiermodell ======
In modernen Systemen ist "Performance pro Watt" oft wichtiger als reine Rechenleistung. Lyx führt ein Modell ein, bei dem der Programmierer den Energie-Fußabdruck direkt im Quellcode oder über Compiler-Flags steuern kann.
===== 1) Die Energy-Levels (1–5) =====
Der Compiler nutzt fünf definierte Stufen, um die Code-Generierung im Backend zu beeinflussen.
^ Level ^ Strategie ^ Beschreibung ^
| 1 | Minimal | Aggressives Power-Saving. Vermeidet SIMD/FPU, reduziert spekulative Ausführung, nutzt energieeffiziente Register-Sets. |
| 2 | Balanced | Ausgewogen. Nutzt Optimierungen, die wenig Mehrverbrauch bei moderatem Geschwindigkeitsgewinn bringen. |
| 3 | Performance | (Standard) Fokus auf Geschwindigkeit. Nutzt alle verfügbaren Instruktionen (SSE/AVX/NEON). |
| 4 | High | Bevorzugt Durchsatz. Nutzt Loop-Unrolling und Inlining massiv aus, auch auf Kosten der Code-Größe. |
| 5 | Extreme | Maximale Takt-Auslastung. Kann Hardware-Spezifika (wie AVX-512) nutzen, die thermisch instabil sein könnten. |
===== 2) Steuerung über Pragmas =====
Mit dem @energy-Pragma kann die Strategie auf Funktions- oder Blockebene festgelegt werden. Dies erlaubt es, unkritische Hintergrundaufgaben (z. B. Logging) sparsam und rechenintensive Kerne (z. B. Kryptographie) performant auszuführen.
// Diese Funktion wird für minimalen Stromverbrauch optimiert
@energy(1)
fn CheckSensors() {
// Backend vermeidet hier z.B. komplexe Sprungvorhersagen
var data := Port.Read(0x3F);
if (data > 0) { ... }
}
// Diese Funktion nutzt das volle Performance-Potenzial
@energy(5)
fn ProcessVideoData(buffer: *uint8) {
// Hier wird massiv SIMD (AVX/NEON) eingesetzt
buffer |> ParallelFilter();
}
===== 3) Backend-Optimierungen =====
Je nach gewähltem Energy-Level verändert das Backend die Code-Erzeugung:
Instruktionswahl: Bei niedrigen Levels werden "teure" Instruktionen (z. B. Divisionen oder komplexe Fließkomma-Operationen) durch einfachere Bit-Shifts oder Integer-Annäherungen ersetzt.
Register-Pressure: Bei Level 1–2 versucht der Compiler, Variablen in Registern zu halten, die weniger Schaltvorgänge (Toggling) auf dem internen Bus verursachen.
Cache-Lokalität: Höhere Energy-Levels investieren mehr Code (Prefetching), um die CPU-Caches warm zu halten, was zwar mehr Energie beim Laden verbraucht, aber die Rechenzeit verkürzt.
===== 4) Energy Statistics (Analyse) =====
Nach der Kompilation mit dem Flag --target-energy gibt Lyx eine Schätzung der benötigten Energie-Einheiten aus:
=== Energy Statistics ===
Estimated energy units: 1450
ALU operations: 890
Memory accesses: 340
Branches: 120
L1 cache footprint: 1024 bytes
Diese Statistiken basieren auf dem im Compiler hinterlegten Energy-Model für die jeweilige Architektur (x86_64 vs. ARM64 vs. Xtensa).
===== 5) Probabilistisches Computing (QBool) =====
Ein Teil des Energy-Modells ist der Typ qbool. Wenn Energie gespart werden muss (Level 1), kann der Compiler qbool-Entscheidungen probabilistisch abkürzen, anstatt teure exakte Vergleiche durchzuführen, sofern die Logik dies erlaubt (z.B. bei heuristischen Filtern).