Profilgestützte Optimierung verwenden

<ph type="x-smartling-placeholder">

Das Android-Build-System für Android 13 und niedriger unterstützt die Verwendung der profile-guided Optimierung (PGO) für native Android-Module mit einem Entwurf Regeln. Auf dieser Seite wird beschrieben, wie Clang PGO kontinuierlich generiert und aktualisiert wird. für PGO verwendete Profile und die Integration von PGO in das Build-System (mit Anwendungsfall).

Hinweis: In diesem Dokument wird die Verwendung von PGO auf der Android-Plattform beschrieben. Weitere Informationen zur Verwendung PGO in einer Android-App, besuche dieser Seite.

Über Clang PGO

Clang kann eine profilgesteuerte Optimierung mit zwei Arten von Profilen:

  • Instrumentierungsbasierte Profile werden aus einem Zielprogramms instrumentiert. Diese Profile sind detailliert und haben eine Laufzeit-Overhead.
  • Auf Stichproben basierende Profile werden in der Regel von Sampling-Hardwarezähler. Sie haben einen geringen Laufzeitaufwand und können ohne Instrumentierung oder Änderung des Binärprogramms erfasst werden. Sie sind weniger detailliert als instrumentierungsbasierte Profile.

Alle Profile sollten aus einer repräsentativen Arbeitslast generiert werden, die die das typische Verhalten der App ausübt. Clang unterstützt sowohl AST-basiert (-fprofile-instr-generate) und LLVM IR-basiert (-fprofile-generate), Android unterstützt nur LLVM IR-basiert für instrumentierungsbasierte PGO.

Die folgenden Flags sind zum Erstellen für die Profilerfassung erforderlich:

  • -fprofile-generate für IR-basierte Instrumentierung. Damit verwendet das Back-End einen gewichteten Minimal-Spanning-Baum-Ansatz, um die Anzahl der Instrumentierungspunkte reduzieren und ihre Platzierung so optimieren, leichten Kanten (verwenden Sie diese Option auch für die Verlinkung). Der Clang Der Treiber übergibt die Profilerstellungslaufzeit automatisch (libclang_rt.profile-arch-android.a) zur Verknüpfung. Diese Bibliothek enthält Routinen zum Schreiben der Profile auf die Festplatte nach dem Programm beenden.
  • -gline-tables-only für stichprobenbasierte Profilerfassung um nur minimale Informationen zur Fehlerbehebung zu generieren.

Ein Profil kann für PGO mit -fprofile-use=pathname oder -fprofile-sample-use=pathname für instrumentierungsbasiert und stichprobenbasierte Profile.

Hinweis:Wenn Änderungen am Code vorgenommen werden, kann Clang den Befehl die Profildaten, die damit generiert werden, -Wprofile-instr-out-of-date Warnung.

PGO verwenden

Die Verwendung von PGO umfasst die folgenden Schritte:

  1. Erstellen Sie die Bibliothek/ausführbare Datei mit Instrumentierung, indem Sie -fprofile-generate für den Compiler und den Linker.
  2. Erfassen Sie Profile, indem Sie eine repräsentative Arbeitslast auf der instrumentierten Binärprogrammen.
  3. Nachverarbeiten der Profile mit dem Dienstprogramm llvm-profdata Weitere Informationen finden Sie unter Umgang mit LLVM. Profildateien) enthält.
  4. Verwenden Sie die Profile, um PGO anzuwenden, indem Sie übergeben -fprofile-use=<>.profdata an den Compiler und Verknüpfung.

Für PGO in Android sollten Profile offline erfasst und eingecheckt werden. um reproduzierbare Builds zu erstellen. Die Profile können als Code sich ständig weiterentwickelt, muss aber regelmäßig neu generiert werden (oder immer dann, wenn Clang eine Warnung ob die Profile veraltet sind.

Profile erfassen

Clang kann Profile verwenden, die beim Ausführen von Benchmarks mit einem instrumentierten Build der Bibliothek oder Stichproben von Hardware-Zählern, wenn der die Benchmark ausgeführt wird. Android unterstützt die Verwendung auf Stichprobenbasis derzeit nicht. Sie müssen Profile also mit einer instrumentierten Build:

  1. Identifizieren Sie eine Benchmark und die Gruppe von Bibliotheken, die von allen gemeinsam genutzten dieser Benchmark.
  2. pgo-Properties zur Benchmark und zu den Bibliotheken hinzufügen (Details) unten).
  3. Android-Build mit einer instrumentierten Kopie dieser Bibliotheken erstellen mit:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark ist ein Platzhalter, der den Sammlung von Bibliotheken, die während des Build-Prozesses instrumentiert wurden. Der tatsächliche Vertreter Eingaben (und möglicherweise eine andere ausführbare Datei, die auf eine Bibliothek verlinkt, nicht spezifisch für PGO sind und nicht in den Dokument.

  1. Der instrumentierte Build wird auf einem Gerät geflasht oder synchronisiert.
  2. Führen Sie die Benchmark aus, um Profile zu erfassen.
  3. Verwenden Sie das llvm-profdata-Tool (wie unten beschrieben), um die Profile nachbearbeiten und für den Eincheck an die Quelle vorbereiten. Baum.

Profile beim Build verwenden

Profile auf einem Android-Gerät in toolchain/pgo-profiles einchecken Baum. Der Name sollte mit den Angaben in der Untergeordnete Property profile_file der Property pgo für in der Bibliothek. Das Build-System übergibt die Profildatei automatisch an Clang. beim Bau der Bibliothek. Das ANDROID_PGO_DISABLE_PROFILE_USE Umgebungsvariable auf true gesetzt werden, PGO vorübergehend deaktivieren und den Leistungsvorteil messen.

Um weitere produktspezifische Profilverzeichnisse anzugeben, hängen Sie diese an die Variable PGO_ADDITIONAL_PROFILE_DIRECTORIES in einer BoardConfig.mk. Wenn zusätzliche Pfade angegeben sind, werden Profile in diese Pfade überschreiben die in toolchain/pgo-profiles.

Wenn Sie ein Release-Image mit dem Ziel dist generieren, make, schreibt das Build-System die Namen der fehlenden Profildateien an $DIST_DIR/pgo_profile_file_missing.txt. Sie können das überprüfen, um zu sehen, welche Profildateien versehentlich gelöscht wurden (die automatisch deaktiviert PGO).

PGO in Android.bp-Dateien aktivieren

Um PGO in Android.bp-Dateien für native Module zu aktivieren, und gib die Property pgo an. Diese Property hat Folgendes: untergeordneten Properties:

Attribut Beschreibung
instrumentation Legen Sie true für PGO mit Instrumentierung fest. Standardwert ist false
sampling Legen Sie true für PGO mit Stichproben fest. Standardwert ist false
benchmarks Liste der Strings. Dieses Modul wurde für die Profilerstellung erstellt, sofern eine Benchmark in der Liste ist im Build ANDROID_PGO_INSTRUMENT angegeben Option.
profile_file Zu verwendende Profildatei (relativ zu toolchain/pgo-profile) mit PGO. Der Build warnt, dass diese Datei nicht existiert, indem Folgendes hinzugefügt wird: Datei in $DIST_DIR/pgo_profile_file_missing.txt es sei denn, das Attribut enable_profile_use ist auf false ODER die Build-Variable ANDROID_PGO_NO_PROFILE_USE ist festgelegt auf true.
enable_profile_use Legen Sie false fest, wenn Profile nicht verwendet werden sollen erstellen. Kann während des Bootstrap-Prozesses verwendet werden, um die Profilerfassung zu ermöglichen PGO vorübergehend deaktivieren. Der Standardwert ist true.
cflags Liste zusätzlicher Flags, die während eines instrumentierten Builds verwendet werden.

Beispiel für ein Modul mit PGO:

cc_library {
    name: "libexample",
    srcs: [
        "src1.cpp",
        "src2.cpp",
    ],
    static: [
        "libstatic1",
        "libstatic2",
    ],
    shared: [
        "libshared1",
    ]
    pgo: {
        instrumentation: true,
        benchmarks: [
            "benchmark1",
            "benchmark2",
        ],
        profile_file: "example.profdata",
    }
}

Wenn die Benchmarks benchmark1 und benchmark2 ein repräsentatives Verhalten für die Bibliotheken libstatic1, libstatic2 oder libshared1, der pgo dieser Bibliotheken auch die Benchmarks enthalten. Die Das defaults-Modul in Android.bp kann einen allgemeinen pgo-Spezifikation für eine Reihe von Bibliotheken, um eine Wiederholung des für mehrere Module erstellen.

Um verschiedene Profildateien auszuwählen oder PGO für eine bestimmte Person zu deaktivieren Architektur enthält, geben Sie profile_file an, enable_profile_use und cflags Unterkünfte pro Architektur. Beispiel (mit Architekturziel in fett):

cc_library {
    name: "libexample",
    srcs: [
          "src1.cpp",
          "src2.cpp",
    ],
    static: [
          "libstatic1",
          "libstatic2",
    ],
    shared: [
          "libshared1",
    ],
    pgo: {
         instrumentation: true,
         benchmarks: [
              "benchmark1",
              "benchmark2",
         ],
    }

    target: {
         android_arm: {
              pgo: {
                   profile_file: "example_arm.profdata",
              }
         },
         android_arm64: {
              pgo: {
                   profile_file: "example_arm64.profdata",
              }
         }
    }
}

Um Verweise auf die Laufzeitbibliothek der Profilerstellung während instrumentierungsbasierte Profilerstellung verwenden, übergeben Sie das Build-Flag -fprofile-generate an die Verknüpfung. Instrumentierte statische Bibliotheken mit PGO, allen gemeinsam genutzten Bibliotheken und allen Binärdateien, die direkt vom die statische Bibliothek auch für PGO instrumentiert sein muss. Solche geteilten Für Bibliotheken oder ausführbare Dateien sind keine PGO-Profile erforderlich. Das Attribut enable_profile_use kann auf false festgelegt werden. Außerhalb dieser Einschränkung können Sie PGO auf jede statische Bibliothek anwenden, Bibliothek oder ausführbare Datei ein.

LLVM-Profildateien verarbeiten

Beim Ausführen einer instrumentierten Bibliothek oder ausführbaren Datei wird eine Profildatei erstellt namens default_unique_id_0.profraw in /data/local/tmp (wobei unique_id ein numerischem Hashwert, der für diese Bibliothek eindeutig ist. Wenn diese Datei bereits vorhanden ist, Die Profilerstellungslaufzeit führt das neue Profil beim Schreiben mit dem alten zusammen. Profilen. Beachte, dass die App nicht auf /data/local/tmp zugreifen kann Entwickler:innen sollten sie irgendwo verwenden, /storage/emulated/0/Android/data/packagename/files. Um den Speicherort der Profildatei zu ändern, legen Sie den LLVM_PROFILE_FILE fest. zur Laufzeit die Umgebungsvariable verwenden.

Das llvm-profdata wird dann die Datei .profraw (und möglicherweise Mehrere .profraw-Dateien) zu einem .profdata zusammenführen Datei:

  llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>

profile.profdata kann dann in die Quelle eingecheckt werden Baum zur Verwendung während des Build-Prozesses.

Werden während einer Benchmark mehrere instrumentierte Binärdateien/Bibliotheken geladen, generiert jede Bibliothek eine separate .profraw-Datei mit einem separaten eindeutige ID. Normalerweise können alle diese Dateien in einer Datei .profdata und wird für den PGO-Build verwendet. Wenn eine Bibliothek von einer anderen Benchmark genutzt wird, muss diese Bibliothek mithilfe von aus beiden Benchmarks. In diesem Fall würde der show Option llvm-profdata ist hilfreich:

  llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw
llvm-profdata show -all-functions default_unique_id.profdata

Um unique_ids einzelnen Bibliotheken zuzuordnen, suchen Sie show-Ausgabe für jede unique_id für einen Funktionsnamen, der ist einzigartig für die Bibliothek.

Fallstudie: PGO for ART

In der Fallstudie wird ART als nachvollziehbares Beispiel präsentiert. ist es jedoch nicht, eine genaue Beschreibung der tatsächlichen Bibliotheken, für die ein Profil für ART erstellt wurde, Abhängigkeiten zu berücksichtigen.

Der dex2oat-Compiler in ART hängt von libart-compiler.so, die wiederum von libart.so Die ART-Laufzeit wird hauptsächlich in libart.so Benchmarks für den Compiler und die Laufzeit unterschiedlich:

Benchmark Bibliotheken mit Profilen
dex2oat dex2oat (ausführbar), libart-compiler.so, libart.so
art_runtime libart.so
  1. Füge die folgende pgo-Property zu dex2oat hinzu: libart-compiler.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Füge libart.so die folgende pgo-Property hinzu:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Instrumentierte Builds für dex2oat und art_runtime für Benchmarks verwendet:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Alternativ können Sie einen einzelnen instrumentierten Build mit allen Bibliotheken erstellen instrumentiert mit:

        make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
        (or)
        make ANDROID_PGO_INSTRUMENT=ALL

    Der zweite Befehl erstellt alle PGO-fähigen Module für Profilerstellung.

  5. Führen Sie die Benchmarks mit dex2oat aus und art_runtime erhalten: <ph type="x-smartling-placeholder">
      </ph>
    • Drei .profraw-Dateien von dex2oat (dex2oat_exe.profdata, dex2oat_libart-compiler.profdata und dexeoat_libart.profdata), identifiziert mit der Methode beschrieben unter Umgang mit dem LLVM-Profil Dateien enthalten.
    • Ein einzelner art_runtime_libart.profdata.
  6. Erstellen Sie eine gemeinsame profdata-Datei für dex2oat ausführbare und libart-compiler.so verwenden:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. Profil für libart.so durch Zusammenführen der Profile abrufen aus den beiden Benchmarks:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    Die Rohdaten für libart.so aus den beiden Profilen können so aussehen: weil sich die Benchmarks in der Anzahl der Testfälle und der Anzahl der für die sie ausgeführt werden. In diesem Fall können Sie eine gewichtete Zusammenführung verwenden:

    llvm-profdata merge -output=libart.profdata \
        -weighted-input=2,dex2oat_libart.profdata \
        -weighted-input=1,art_runtime_libart.profdata

    Mit dem obigen Befehl wird dem Profil die doppelte Gewichtung dex2oat Die tatsächliche Gewichtung sollte anhand der Domain bestimmt werden. Wissen oder Experimente.

  8. Prüfen Sie die Profildateien dex2oat.profdata und libart.profdata in toolchain/pgo-profiles für während des Build-Vorgangs verwendet werden.