Produktneuheiten

Android-Leistung steigern: AutoFDO für den Kernel

Lesezeit: 4 Minuten
Yabin Cui
Softwaretechniker

Wir sind das Android LLVM-Toolchain-Team. Eine unserer obersten Prioritäten ist die Verbesserung der Android-Leistung durch Optimierungstechniken im LLVM-Ökosystem. Wir suchen ständig nach Möglichkeiten, Android schneller, flüssiger und effizienter zu machen. Ein Großteil unserer Optimierungsarbeit findet zwar im Userspace statt, der Kernel bleibt aber das Herzstück des Systems. Heute möchten wir Ihnen vorstellen, wie wir Automatic Feedback-Directed Optimization (AutoFDO) in den Android-Kernel integrieren, um die Leistung für Nutzer deutlich zu verbessern.

Was ist AutoFDO?

Bei einem standardmäßigen Software-Build trifft der Compiler Tausende kleiner Entscheidungen, z. B. ob eine Funktion inline ausgeführt werden soll und welcher Zweig einer Bedingung wahrscheinlich ausgeführt wird. Diese Entscheidungen basieren auf statischen Code-Hinweisen. Diese Heuristiken sind zwar nützlich, aber sie sagen nicht immer genau voraus, wie der Code bei der tatsächlichen Nutzung des Smartphones ausgeführt wird.

AutoFDO ändert dies, indem es den Compiler anhand von Mustern der tatsächlichen Ausführung steuert. Diese Muster stellen die häufigsten Ausführungspfade für Anweisungen dar, die der Code während der tatsächlichen Verwendung durchläuft. Sie werden erfasst, indem der Verzweigungsverlauf der CPU aufgezeichnet wird. Diese Daten können zwar von Flottengeräten erhoben werden, für den Kernel werden sie jedoch in einer Laborumgebung mit repräsentativen Arbeitslasten synthetisiert, z. B. durch Ausführen der 100 beliebtesten Apps. Wir verwenden ein Sampling-Profiler, um diese Daten zu erfassen und zu ermitteln, welche Teile des Codes „aktiv“ (häufig verwendet) und welche „inaktiv“ sind. Wenn wir den Kernel mit diesen Profilen neu erstellen, kann der Compiler viel intelligentere Optimierungsentscheidungen treffen, die auf tatsächliche Android-Arbeitslasten zugeschnitten sind.

Um die Auswirkungen dieser Optimierung zu verstehen, sollten Sie die folgenden wichtigen Fakten berücksichtigen:

  • Unter Android macht der Kernel etwa 40% der CPU-Zeit aus.
  • Wir verwenden AutoFDO bereits, um native ausführbare Dateien und Bibliotheken im Userspace zu optimieren. Dadurch wird der Kaltstart von Apps um etwa 4% und die Bootzeit um 1% verkürzt.

Leistungssteigerungen in der Praxis

Durch die Nutzung von Profilen aus kontrollierten Laborumgebungen konnten wir beeindruckende Verbesserungen bei wichtigen Android-Messwerten erzielen. Diese Profile wurden durch Crawling und Starten von Apps erhoben und auf Pixel-Geräten mit den Kernels 6.1, 6.6 und 6.12 gemessen.

Die wichtigsten Verbesserungen sind unten aufgeführt. Details zu den AutoFDO-Profilen für diese Kernelversionen finden Sie in den entsprechenden Android-Kernel-Repositories für die Kernel android16-6.12 und android15-6.6.

boosting_2.png

Das sind nicht nur theoretische Zahlen. Das führt zu einer schnelleren Benutzeroberfläche, einem schnelleren Wechsel zwischen Apps, einer längeren Akkulaufzeit und einem insgesamt reaktionsschnelleren Gerät für den Endnutzer.

Funktionsweise: Die Pipeline

Unsere Bereitstellungsstrategie umfasst eine ausgefeilte Pipeline, um dafür zu sorgen, dass Profile relevant bleiben und die Leistung stabil bleibt.

boosting_3.png

Schritt 1: Profilerstellung

Während wir uns bei der Profilerstellung von Binärdateien im Userspace auf unsere interne Testflotte verlassen, sind wir für das Generic Kernel Image (GKI) auf eine kontrollierte Laborumgebung umgestiegen. Durch die Entkopplung des Profilings vom Geräte-Releasezyklus sind flexible, sofortige Updates unabhängig von den bereitgestellten Kernelversionen möglich. Wichtig ist, dass Tests bestätigen, dass diese laborgestützten Daten Leistungssteigerungen ermöglichen, die mit denen von realen Flotten vergleichbar sind.

  • Tools und Umgebung:Wir flashen Testgeräte mit dem neuesten Kernel-Image und verwenden simpleperf, um Streams mit ausgeführten Befehlen zu erfassen. Dieser Prozess basiert auf Hardwarefunktionen zum Aufzeichnen des Branching-Verlaufs, insbesondere auf der Verwendung von  ARM Embedded Trace Extension (ETE) und ARM Trace Buffer Extension (TRBE) auf Pixel-Geräten.
  • Arbeitslasten: Wir erstellen eine repräsentative Arbeitslast mit den 100 beliebtesten Apps aus der Android App Compatibility Test Suite (C-Suite). Um möglichst genaue Daten zu erfassen, konzentrieren wir uns auf Folgendes:
    • App-Start:Optimierung für die am deutlichsten sichtbaren Nutzerverzögerungen
    • KI-gestütztes App-Crawling:Simulation fortlaufender, sich entwickelnder Nutzerinteraktionen
    • Systemweites Monitoring:Erfassung nicht nur von Aktivitäten der im Vordergrund ausgeführten App, sondern auch von wichtigen Hintergrundprozessen und der prozessübergreifenden Kommunikation
  • Validierung:Diese synthetische Arbeitslast weist eine Ähnlichkeit von 85% mit Ausführungsmustern auf, die von unserer internen Flotte erfasst wurden.
  • Gezielte Daten:Durch die Wiederholung dieser Tests erfassen wir hochwertige Ausführungsmuster, die die tatsächliche Nutzerinteraktion mit den beliebtesten Anwendungen genau widerspiegeln. Außerdem können wir mit diesem erweiterbaren Framework nahtlos zusätzliche Arbeitslasten und Benchmarks einbinden, um die Abdeckung zu erweitern.

Schritt 2: Profilverarbeitung

Wir verarbeiten die Rohdaten der Traces nach, um sicherzustellen, dass sie sauber, effektiv und für den Compiler bereit sind.

  • Aggregation:Wir konsolidieren Daten aus mehreren Testläufen und Geräten in einer einzigen Systemansicht.
  • Konvertierung : Wir konvertieren Roh-Traces in das AutoFDO-Profilformat und filtern bei Bedarf unerwünschte Symbole heraus.
  • Profilbereinigung:Wir bereinigen Profile, um Daten für „kalte“ Funktionen zu entfernen, damit sie standardmäßig optimiert werden können. So werden Regressionen in selten verwendetem Code verhindert und die Binärgröße wird nicht unnötig erhöht.

Schritt 3: Profil testen

Vor der Bereitstellung werden Profile streng geprüft, um sicherzustellen, dass sie konsistente Leistungssteigerungen ohne Stabilitätsrisiken bieten.

  • Profil- und Binäranalyse:Wir vergleichen den Inhalt des neuen Profils (einschließlich Hot-Funktionen, Anzahl der Stichproben und Profilgröße) streng mit früheren Versionen. Wir verwenden das Profil auch, um ein neues Kernel-Image zu erstellen. Dabei werden Binärdateien analysiert, um sicherzustellen, dass Änderungen am Textabschnitt den Erwartungen entsprechen.
  • Leistungsüberprüfung:Wir führen gezielte Benchmarks für das neue Kernel-Image aus. So wird bestätigt, dass die durch frühere Baselines erzielten Leistungssteigerungen beibehalten werden.

Kontinuierliche Updates

Code „driftet“ im Laufe der Zeit. Ein statisches Profil würde also irgendwann seine Effektivität verlieren. Um eine optimale Leistung zu erzielen, wird die Pipeline kontinuierlich ausgeführt, um regelmäßige Updates zu ermöglichen:

  • Regelmäßige Aktualisierung:Wir aktualisieren Profile in Android-Kernel-LTS-Branches vor jedem GKI-Release, damit jeder Build die neuesten Profildaten enthält.
  • Zukünftige Erweiterung:Wir stellen diese Updates derzeit für die Branches android16-6.12 und android15-6.6 bereit und werden die Unterstützung auf neuere GKI-Versionen wie die kommende android17-6.18 ausweiten.

Stabilität gewährleisten

Eine häufig gestellte Frage zur profilgesteuerten Optimierung ist, ob sie Stabilitätsrisiken birgt. Da AutoFDO in erster Linie Compiler-Heuristiken wie das Inlining von Funktionen und das Code-Layout beeinflusst und nicht die Logik des Quellcodes ändert, bleibt die funktionale Integrität des Kernels erhalten. Diese Technologie hat sich bereits in großem Maßstab bewährt und dient seit Jahren als Standardoptimierung für Android-Plattformbibliotheken, ChromeOS und die Serverinfrastruktur von Google.

Um ein einheitliches Verhalten zu gewährleisten, wenden wir standardmäßig eine „conservative by default“-Strategie an. Funktionen, die nicht in unseren High-Fidelity-Profilen erfasst werden, werden mit Standard-Compilermethoden optimiert. So wird sichergestellt, dass sich die „kalten“ oder selten ausgeführten Teile des Kernels genau wie in einem Standard-Build verhalten. Dadurch werden Leistungsbeeinträchtigungen oder unerwartetes Verhalten in Grenzsituationen verhindert.

Unsere Zukunftspläne

Wir stellen AutoFDO derzeit in den Zweigen android16-6.12 und android15-6.6 bereit. Über diese erste Einführung hinaus sehen wir mehrere vielversprechende Möglichkeiten, die Technologie weiter zu verbessern:

  • Größere Reichweite:Wir freuen uns darauf, AutoFDO-Profile für neuere GKI-Kernelversionen und zusätzliche Build-Ziele über die aktuelle aarch64-Unterstützung hinaus bereitzustellen.
  • GKI-Moduloptimierung:Derzeit konzentriert sich unsere Optimierung auf die binäre Hauptkerneldatei (vmlinux). Wenn AutoFDO auf GKI-Module ausgeweitet wird, könnte dies die Leistung eines größeren Teils des Kernel-Subsystems verbessern.
  • Unterstützung von Anbietermodulen:Wir möchten AutoFDO auch für Anbietermodule unterstützen, die mit dem Driver Development Kit (DDK) erstellt wurden. Da die Unterstützung bereits in unserem Build-System (Kleaf) und in unseren Profilerstellungstools (simpleperf) verfügbar ist, können Anbieter diese Optimierungstechniken auf ihre spezifischen Hardwaretreiber anwenden.
  • Größere Profilabdeckung:Es besteht die Möglichkeit, Profile für eine größere Bandbreite von wichtigen Nutzerverhalten (Critical User Journeys, CUJs) zu erfassen, um sie zu optimieren.

Durch die Integration von AutoFDO in den Android-Kernel sorgen wir dafür, dass die Grundlage des Betriebssystems für die Art und Weise optimiert ist, wie Sie Ihr Gerät täglich nutzen.

Verfasst von:

Weiterlesen