Plik zamówienia to nowa metoda optymalizacji kreatora linków. Są to pliki tekstowe zawierające symbole reprezentujące funkcje. Łączniki, takie jak lld, używają plików kolejności do układania funkcji w określonej kolejności. Te pliki binarne i biblioteki z uporządkowanymi symbolami ograniczają liczbę błędów stron i skrócić czas uruchamiania programu dzięki skutecznemu ładowaniu symboli podczas zimnego startu programu.
Funkcje pliku zamówienia można dodać do aplikacji, wykonując 3 czynności kroki:
- Wygeneruj profile i plik mapowania
- Utwórz plik zamówienia na podstawie profili i pliku mapowania
- Do układania symboli użyj pliku zamówienia w kompilacji dotyczącej wersji.
Generuj plik zamówienia
Generowanie pliku zamówienia składa się z trzech kroków:
- Utwórz instrumentowaną wersję aplikacji, która zapisuje plik zamówienia
- Uruchom aplikację, aby wygenerować profile
- Przetwarzanie końcowe profili i pliku mapowania
Utwórz kompilację z instrumentacją
Profile są generowane przez uruchomienie zinstrumentowanej kompilacji aplikacji.
Kompilacja z instrumentacją wymaga dodania elementu -forder-file-instrumentation
do
flagi kompilatora i łączącego
-mllvm -orderfile-write-mapping=<filename>-mapping.txt
były ściśle dodawane do flag kompilatora.
Flaga instrumentacji umożliwia instrumentację pliku zamówienia na potrzeby profilowania oraz
wczytuje konkretną bibliotekę potrzebną do profilowania.
Z drugiej strony flaga mapowania generuje tylko plik mapowania, który pokazuje
Skrót MD5 dla każdej funkcji w pliku binarnym lub bibliotece.
Pamiętaj też, by przekazać wszystkie flagi optymalizacji, ale -O0
, ponieważ obie
flaga instrumentacji i flagi mapowania wymagają jednego.
Jeśli nie zostanie przesłana żadna flaga optymalizacji, plik mapowania nie zostanie wygenerowany, a parametr
kompilacja instrumentowana może zwrócić do pliku profilu błędne hasze.
ndk-build
Pamiętaj, aby kompilować za pomocą APP_OPTIM=release
, aby funkcja ndk-build korzystała z optymalizacji
inny niż -O0
. Jeśli używasz AGP, ta funkcja jest dostępna automatycznie
do tworzenia kampanii.
LOCAL_CFLAGS += \
-forder-file-instrumentation \
-mllvm -orderfile-write-mapping=mapping.txt \
LOCAL_LDFLAGS += -forder-file-instrumentation
CMake
Upewnij się, że używasz pola CMAKE_BUILD_TYPE
innego niż Debug
, więc CMake używa parametru
tryb optymalizacji inny niż -O0
. W przypadku tworzenia za pomocą AGP jest to ustawienie automatyczne
dla kompilacji wersji.
target_compile_options(orderfiledemo PRIVATE
-forder-file-instrumentation
-mllvm -orderfile-write-mapping=mapping.txt
)
target_link_options(orderfiledemo PRIVATE -forder-file-instrumentation)
Inne systemy kompilacji
Skompiluj kod za pomocą polecenia -forder-file-instrumentation -O1 -mllvm
-orderfile-write-mapping=mapping.txt
.
Parametr -O1
nie jest wymagany, ale nie używaj właściwości -O0
.
Pomiń -mllvm -orderfile-write-mapping=mapping.txt
podczas łączenia.
Żadne z tych flag nie są potrzebne w przypadku kompilacji wersji, więc powinny być kontrolowane przez i zmiennej kompilacji. Dla uproszczenia możesz to zrobić w pliku CMakeLists.txt, jak w naszym sample.
Tworzenie biblioteki plików zamówienia
Oprócz flag trzeba skonfigurować plik profilu oraz instrumentowany plik binarny musi jawnie aktywować zapis profilu podczas
- Zadzwoń do firmy
__llvm_profile_set_filename(PROFILE_DIR "/<filename>-%m.profraw")
i poproś o skonfigurować ścieżkę profilu. Mimo że przekazany argument to<filename>-%m.profraw
, plik profilu jest zapisywany jako<filename>-%m.profraw.order
Upewnij się, że aplikacjaPROFILE_DIR
może zapisywać tekst i masz dostęp do katalogu.- Ze względu na profilowanie wielu bibliotek udostępnionych usługa
%m
jest przydatna, rozwija się do unikalnego podpisu modułu dla biblioteki, co skutkuje dla każdej biblioteki. Więcej specyfikacji wzorców znajdziesz na ten link.
- Ze względu na profilowanie wielu bibliotek udostępnionych usługa
- Zadzwoń pod numer
__llvm_profile_initialize_file()
, aby skonfigurować plik profilu - Wywołaj
__llvm_orderfile_dump()
, aby bezpośrednio zapisać plik profilu
Profile są zbierane w pamięci, a funkcja zrzutu zapisuje je w . Musisz upewnić się, że funkcja zrzutu jest wywoływana po zakończeniu uruchamiania tak aby plik profilu zawierał wszystkie symbole do końca uruchamiania.
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;
}
Uruchamianie kompilacji dla profili
Uruchom aplikację z instrumentami na urządzeniu fizycznym lub wirtualnym, aby wygenerować
profili.
Pliki profilu możesz rozpakować za pomocą pliku adb pull
.
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 .
Jak wspomnieliśmy wcześniej, upewnij się, że folder zawierający zapisany plik profilu są dostępne dla Ciebie. Jeśli jest to urządzenie wirtualne, lepiej unikać emulatorów w Sklepie Play. z powodu braku dostępu do wielu folderów.
Przetwarzanie końcowej pliku profilu i pliku mapowania
Po pobraniu profili musisz znaleźć plik mapowania i dokonać konwersji do formatu szesnastkowego każdego profilu. Plik mapowania można zwykle znaleźć w folderze kompilacji aplikacji. Jeśli dysponujesz obydwoma, możesz użyć naszego skryptu, pobierz plik profilu i odpowiedni plik mapowania, aby wygenerować plik zamówienia.
Linux/macOS/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
Jeśli chcesz dowiedzieć się więcej o tym skrypcie, tutaj znajdziesz README.
Tworzenie aplikacji przy użyciu pliku zamówienia
Po wygenerowaniu pliku zamówienia usuń wcześniejsze flagi i
, ponieważ są one przeznaczone tylko do kroków generowania.
Musisz tylko przekazać -Wl,--symbol-ordering-file=<filename>.orderfile
do
flagą Google Analytics.
Czasami symboli nie można znaleźć lub przesunąć, co powoduje wyświetlanie ostrzeżeń.
może przekazać -Wl,--no-warn-symbol-ordering
, aby powstrzymać te ostrzeżenia.
ndk-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
)
Inne systemy kompilacji
Skompiluj kod za pomocą polecenia -Wl,--symbol-ordering-file=<filename>.orderfile
-Wl,--no-warn-symbol-ordering
.
Więcej informacji znajdziesz w przykładowym pliku zamówienia.
Szczegóły implementacji pliku zamówienia
Pliki zamówień można generować na wiele sposobów i używać ich do tworzenia. NDK wykorzystuje metodę LLVM, więc jest to najbardziej przydatne w przypadku udostępnianych zasobów w języku C lub C++ nad rzeczywistą aplikacją Java lub Kotlin. Clang pobiera każdą nazwę funkcji (symbol) i tworzy jej skrót MD5, zwraca to powiązanie do pliku mapowania. Skrót MD5 funkcji jest zapisywany w pliku profilu (w formacie profraw), gdy jest wykonywana po raz pierwszy. Żadne kolejne wykonania funkcji nie będą zapisywać jej skrótu MD5 w funkcji profilu, ponieważ chce on uniknąć duplikatów. W rezultacie w zamówieniu rejestrowane jest tylko pierwsze wykonanie funkcji. Przeglądając plik profilu i plik mapowania, możesz przyjąć każdy hasz MD5. i zastąp ją odpowiednią funkcją.
Przykłady pliku profilu w formacie szesnastkowym oraz pliku mapowania znajduje się jako example.prof i example-mapping.txt.