Dateien bestellen

Die Bestelldatei ist eine kürzliche Methode zur Verknüpfungsoptimierung. Bei diesen Bestelldateien handelt es sich um Textdateien, die Symbole für Funktionen enthalten. Linker wie „lld“ verwenden Reihenfolgedateien, um Funktionen in einer bestimmten Reihenfolge zu erstellen. Diese Binärdateien oder Bibliotheken mit geordneten Symbolen reduzieren Seitenfehler und die Startzeit eines Programms durch effizientes Laden von Symbolen verbessern während des Kaltstarts eines Programms.

Sie können Ihrer Anwendung Funktionen für Bestelldateien hinzufügen, indem Sie drei Schritte:

  1. Profile und Zuordnungsdatei generieren
  2. Auftragsdatei aus Profilen und Zuordnungsdatei erstellen
  3. Verwenden Sie die Bestelldatei während des Release-Builds für das Layout der Symbole.

Auftragsdatei erstellen

Die Erstellung einer Auftragsdatei umfasst drei Schritte:

  1. Instrumentierte Version der App erstellen, die die Bestelldatei schreibt
  2. Anwendung ausführen, um Profile zu generieren
  3. Profile und Zuordnungsdatei nachbearbeiten

Instrumentierten Build erstellen

Die Profile werden generiert, indem ein instrumentierter Build der Anwendung ausgeführt wird. Für einen instrumentierten Build muss -forder-file-instrumentation sowohl dem mit Compiler- und Linker-Flags -mllvm -orderfile-write-mapping=<filename>-mapping.txt den Compiler-Flags hinzugefügt werden. Das Instrumentierungs-Flag ermöglicht die Instrumentierung von Auftragsdateien für die Profilerstellung und lädt die spezifische Bibliothek, die für die Profilerstellung benötigt wird. Andererseits gibt das Zuordnungs-Flag nur die Zuordnungsdatei aus, die das MD5-Hash für jede Funktion in der Binärdatei oder der Bibliothek.

Achten Sie außerdem darauf, alle Optimierungs-Flags außer -O0 zu übergeben, da sowohl Instrumentierungs- und Zuordnungs-Flags erfordern ein solches Flag. Wenn kein Optimierungs-Flag übergeben wird, wird die Zuordnungsdatei nicht generiert und der instrumentierter Build möglicherweise falsche Hashes an die Profildatei ausgibt.

NK-Build

Achten Sie darauf, mit APP_OPTIM=release zu erstellen, damit „ndk-build“ eine Optimierung verwendet anderen Modus als -O0. Beim Erstellen mit AGP erfolgt dies automatisch für die Veröffentlichung baut.

LOCAL_CFLAGS += \
    -forder-file-instrumentation \
    -mllvm -orderfile-write-mapping=mapping.txt \

LOCAL_LDFLAGS += -forder-file-instrumentation

CMake

Achten Sie darauf, eine andere CMAKE_BUILD_TYPE als Debug zu verwenden, damit CMake einen anderer Optimierungsmodus als -O0 Beim Erstellen mit AGP erfolgt dies automatisch für Release-Builds.

target_compile_options(orderfiledemo PRIVATE
    -forder-file-instrumentation
    -mllvm -orderfile-write-mapping=mapping.txt
)
target_link_options(orderfiledemo PRIVATE -forder-file-instrumentation)

Andere Build-Systeme

Kompilieren Sie Ihren Code mit -forder-file-instrumentation -O1 -mllvm -orderfile-write-mapping=mapping.txt.

-O1 ist nicht erforderlich, aber Sie dürfen -O0 nicht verwenden.

Lassen Sie beim Verknüpfen -mllvm -orderfile-write-mapping=mapping.txt weg.

Alle diese Flags sind für einen Release-Build nicht erforderlich. eine Build-Variable. Der Einfachheit halber können Sie alles in der Datei CMakeLists.txt wie in der Beispiel:

Auftragsdateibibliothek erstellen

Zusätzlich zu den Flags muss die Profildatei eingerichtet und der muss eine instrumentierte Binärdatei explizit einen Profilschreibvorgang auslösen, Ausführung.

  • __llvm_profile_set_filename(PROFILE_DIR "/<filename>-%m.profraw") anrufen für und richten Sie den Profilpfad ein. Obwohl das übergebene Argument <filename>-%m.profraw, die Profildatei wird gespeichert unter <filename>-%m.profraw.order. Prüfen, ob PROFILE_DIR von der App beschreibbar ist und Sie haben Zugriff auf das Verzeichnis.
    • Da für viele geteilte Fotogalerien Profile erstellt werden, ist %m nützlich, weil erweitert sich zu einer eindeutigen Modulsignatur für die Bibliothek, was zu einem ein separates Profil für jede Bibliothek. Weitere Musterspezifizierer finden Sie in diesen Link.
  • __llvm_profile_initialize_file() aufrufen, um die Profildatei einzurichten
  • __llvm_orderfile_dump() aufrufen, um explizit in die Profildatei zu schreiben

Die Profile werden im Arbeitsspeicher gesammelt und von der Dump-Funktion in den -Datei. Sie müssen darauf achten, dass die Dump-Funktion am Ende des Starts aufgerufen wird sodass Ihre Profildatei bis zum Ende des Startvorgangs alle Symbole enthält.

extern "C" {
extern int __llvm_profile_set_filename(const char*);
extern int __llvm_profile_initialize_file(void);
extern int __llvm_orderfile_dump(void);
}

#define PROFILE_DIR "<location-writable-from-app>"
void workload() {
  // ...
  // run workload
  // ...

  // set path and write profiles after workload execution
  __llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw");
  __llvm_profile_initialize_file();
  __llvm_orderfile_dump();
  return;
}

Build für Profile ausführen

Führen Sie die instrumentierte App entweder auf einem physischen oder virtuellen Gerät aus, um die Profilen. Sie können die Profildateien mit adb pull extrahieren.

adb shell "run-as <package-name> sh -c 'cat /data/user/0/<package-name>/cache/default-%m.profraw.order' | cat > /data/local/tmp/default-%m.profraw.order"
adb pull /data/local/tmp/default-%m.profraw.order .

Stellen Sie wie bereits erwähnt sicher, dass der Ordner, der die geschriebene Profildatei enthält, auf die Sie zugreifen können. Wenn es sich um ein virtuelles Gerät handelt, solltest du die Emulatoren mit dem Play Store vermeiden. weil sie keinen Zugriff auf viele Ordner haben.

Profil- und Zuordnungsdatei nachbearbeiten

Wenn Sie die Profile erhalten, müssen Sie die Zuordnungsdatei suchen und konvertieren Profil in ein Hexadezimalformat umwandeln. In der Regel befindet sich die Zuordnungsdatei im Build-Ordner der Anwendung. Wenn Sie beides haben, können Sie unser Skript verwenden. , um mithilfe einer Profildatei und der richtigen Zuordnungsdatei eine Auftragsdatei zu generieren.

Linux/Mac/ChromeOS

hexdump -C default-%m.profraw.order > default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt

Windows

certutil -f -encodeHex default-%m.profraw.order default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt

Weitere Informationen zum Skript finden Sie in diesem README.

Auftragsdatei zum Erstellen der Anwendung verwenden

Nach dem Generieren einer Bestelldatei sollten Sie die früheren Flags und den Funktionen zu sortieren, da diese nur für Generierungsschritte gedacht sind. Sie müssen nur -Wl,--symbol-ordering-file=<filename>.orderfile an den Kompilierungs- und Verknüpfungs-Flags. Manchmal können Symbole nicht gefunden werden oder sich nicht bewegen und Warnungen ausgeben, damit Sie können -Wl,--no-warn-symbol-ordering übergeben, um diese Warnungen zu unterdrücken.

NK-Build

LOCAL_CFLAGS += \
    -Wl,--symbol-ordering-file=<filename>.orderfile \
    -Wl,--no-warn-symbol-ordering \

LOCAL_LDFLAGS += \
    -Wl,--symbol-ordering-file=<filename>.orderfile \
    -Wl,--no-warn-symbol-ordering \

CMake

target_compile_options(orderfiledemo PRIVATE
    -Wl,--symbol-ordering-file=<filename>.orderfile
    -Wl,--no-warn-symbol-ordering
)
target_link_options(orderfiledemo PRIVATE
    -Wl,--symbol-ordering-file=<filename>.orderfile
    -Wl,--no-warn-symbol-ordering
)

Andere Build-Systeme

Kompilieren Sie Ihren Code mit -Wl,--symbol-ordering-file=<filename>.orderfile -Wl,--no-warn-symbol-ordering.

Weitere Informationen finden Sie im Beispiel für eine Bestelldatei.

Details zur Implementierung der Bestelldatei

Es gibt viele Möglichkeiten, Auftragsdateien zu generieren und für die Erstellung zu verwenden. Das NDK verwendet die LLVM-Methode. Sie eignet sich daher am besten für C- oder C++- statt der Java- oder Kotlin-App. Clang verwendet jeden Funktionsnamen (Symbol) und erstellt einen MD5-Hash davon. gibt diese Beziehung zu einer Zuordnungsdatei aus. Der MD5-Hash einer Funktion wird in die Profildatei (profraw-Format) geschrieben, wenn der die Funktion zum ersten Mal ausgeführt wird. Bei nachfolgenden Ausführungen der Funktion wird der MD5-Hash nicht in den Profildatei erstellt, weil so Duplikate vermieden werden sollen. Daher wird nur die erste Ausführung der Funktion in der Reihenfolge aufgezeichnet. In der Profildatei und der Zuordnungsdatei können Sie jeden MD5-Hashwert und durch die entsprechende Funktion ersetzen und eine Bestelldatei abrufen.

Beispiele für eine Profildatei im Hexadezimalformat und eine Zuordnungsdatei sind gefunden als beispiel.prof bzw. example-mapping.txt.