ILP32 für 64-Bit-CPUs
32-Bit-Zeiger mit dem vollen 64-Bit-Befehlssatz: bis zu 30 % weniger Speicher, für einige Prozent Geschwindigkeit. Unsere erste Architektur ist AArch64, für Embedded Linux auf Kernen, die kein 32-Bit-Arm mehr ausführen.
Was ist ILP32?
Ein ILP32-Programm ist ein 64-Bit-Programm: Es nutzt die 64-Bit-Befehle und -Register. Nur Speicheradressen
(Zeiger) werden in 4 statt 8 Byte gespeichert. Kürzere Adressen bedeuten kleinere Daten, das Programm braucht
also weniger Speicher. Die Grenze liegt bei 4 GB Speicher pro Programm, was für Router und kleine Boards reicht.
Der Name bedeutet, dass int, long und Zeiger 32 Bit breit sind; normales 64-Bit-Linux ist
LP64, mit 64-Bit-long und -Zeigern.
| 32-Bit-Arm (armhf) | normales 64-Bit (LP64) | ILP32 | |
|---|---|---|---|
| Befehle und Register | 32 Bit | 64 Bit | 64 Bit |
| Adressgröße (Zeiger) | 4 Byte | 8 Byte | 4 Byte |
| Speicherbedarf | gering | hoch | gering |
| Läuft auf neueren Arm-Kernen | nein | ja | ja |
| Speicher pro Programm | 4 GB | weit mehr | 4 GB |
Warum ILP32?
Embedded-Geräte haben knappe Speicherbudgets, oft 128–512 MB, und DRAM wird immer teurer. Früher war auf Arm 32-Bit-Arm (armhf) die speichersparende Wahl, aber neuere Kerne (Cortex-A715/A720, Cortex-A520, Cortex-X3 und neuer) führen keinen AArch32-Code mehr aus. ILP32 behält die Speicherersparnis und läuft auf diesen reinen AArch64-Kernen.
- Kleinere Zeiger und Datenstrukturen: weniger Speicher, bessere Cache-Nutzung.
- Der volle 64-Bit-Befehlssatz und die Register bleiben (auf AArch64: 31 Universalregister).
- Der Kernel bleibt 64-bittig; ILP32- und LP64-Programme laufen nebeneinander.
- 64-Bit-
time_t: kein Jahr-2038-Problem.
Der Kompromiss: ILP32 ist beim gleichen Build einige Prozent langsamer als LP64, unter anderem weil Adressrechnung mit 32-Bit-Zeigern bei 4 GiB umbrechen muss und der Compiler deshalb manchmal zusätzliche Befehle braucht. Siehe die Messungen. Die Idee ist nicht auf Arm beschränkt: Linux hat seit 2012 x32 für x86-64, Apple verwendet seit 2018 arm64_32 auf der Apple Watch, und die RISC-V-psABI führt eine experimentelle RV64ILP32-ABI (Architekturen).
Die Herausforderung
Auf AArch64 zieht sich die Upstream-Unterstützung zurück: Die Linux-ILP32-ABI wurde nie gemergt, glibc
hat ihre Portierung nie übernommen, GCC 15 hat -mabi=ilp32 als veraltet markiert, und Arm hat
ILP32 aus seinen AArch64-ABI-Dokumenten entfernt. Wir halten den ganzen Stack lauffähig und gemeinsam
getestet: Kernel, C-Bibliotheken, Compiler, ILP32Wrt und Debian-Pakete, durchgehend mit 64-Bit-time_t.
Was wir bieten
Gemessen
| OpenWrt One unter Last | LP64 | ILP32 | Änderung |
|---|---|---|---|
| Userspace-Speicher (PSS) | 38.3 MB | 28.9 MB | -24.6% |
| Freier Speicher | 863.6 MB | 872.2 MB | +8.6 MB |
| Geschwindigkeit (vier Zeitmessungen, mit GCC gebaut) | 2–11 % langsamer | ||
Gleicher Quellbaum, gleiche Pakete und Kernel-Konfiguration, beide mit GCC 14.3 gebaut; nur die Userspace-ABI unterscheidet sich. Alle Ergebnisse und die Methode.
Stand
- Getestet in QEMU (Cortex-A35/A53 sowie
-cpu maxmit PAC, BTI und SVE) und auf Hardware: OpenWrt One und Raspberry Pi 3 B+ (ILP32Wrt); Raspberry Pi 3 B+, ESPRESSObin, ein Cortex-A72-Board und ein Cortex-A35-Board (Debian 13). - GCC kann bei ILP32 keine Rücksprungadressen signieren (
pac-ret); clang 22 mit unseren Patches kann es. - Noch nicht portiert: die LLVM-Laufzeitbibliotheken (compiler-rt, libunwind, libc++) und Sprachlaufzeiten wie Java und Node.js.
Mitmachen
Fragen, Ideen und Ergebnisse von euren eigenen Boards sind in den Discussions
willkommen. Jede und jeder darf unsere Patches unter eigenem Namen upstream einreichen (bitte das
ursprüngliche Signed-off-by behalten), und Maintainer sind willkommen, auch für neue
Architekturen. Kontakt: [email protected].