====== 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).