Optymalizacja oparta na profilu

System kompilacji Androida na Androida 13 i starszych wersji obsługuje za pomocą przewodnika po profilu Clangu optymalizacja (PGO) w natywnych modułach Androida z kompilacją plan reguł. Na tej stronie dowiesz się, jak w ramach Clang PGO generować i aktualizować oraz jak zintegrować PGO z systemem kompilacji (z przypadku użycia).

Uwaga: w tym dokumencie opisano zastosowanie PGO na platformie Android. Aby dowiedzieć się więcej o korzystaniu z usługi, PGO w aplikacji na Androida, wejdź na tę stronę.

Informacje o Clang PGO

Usługa Clang może przeprowadzać optymalizację opartą na profilu za pomocą 2 typów: profile:

  • Profile oparte na narzędziach są generowane na podstawie ukierunkowany program docelowy. Profile te są szczegółowe i narzucają wysoki narzut środowiska wykonawczego.
  • Profile oparte na próbkowaniu są zwykle tworzone przez za pomocą liczników próbkowania sprzętowego. Wiąże się to z niskim nakładem pracy podczas działania i mogą być zebrane bez konieczności użycia narzędzi ani modyfikacji pliku binarnego. Ta są mniej szczegółowe niż profile oparte na instrumentach.

Wszystkie profile powinny być generowane z reprezentatywnego zadania, które wykonuje typowe działanie aplikacji. Choć Clang obsługuje Oparte na AST (-fprofile-instr-generate) i LLVM na podczerwień (-fprofile-generate), Android obsługuje wyłącznie modele LLVM IR oparte na: PGO oparty na instrumentacjach.

Do kompilacji profilu potrzebne są te flagi:

  • -fprofile-generate dla instrumentacji opartej na podczerwień. W związku z tym bazuje na ważonym, minimalnym stopniu rozpiętości zmniejszyć liczbę punktów instrumentacyjnych i zoptymalizować ich rozmieszczenie małe krawędzie (należy użyć tej opcji również w przypadku kroku połączenia). Melancholijna sterownik automatycznie przekazuje środowisko wykonawcze profilowania (libclang_rt.profile-arch-android.a) do tagu łączącego. Ta biblioteka zawiera rutyny zapisujące profile na dysk po programie .
  • -gline-tables-only do gromadzenia danych na podstawie próbkowania aby wygenerować jak najmniej danych debugowania.

Profil może być używany do celów PGO za pomocą: -fprofile-use=pathname lub -fprofile-sample-use=pathname w przypadku opcji opartej na instrumentacji i profili opartych na próbkowaniu.

Uwaga: jeśli po wprowadzeniu zmian w kodzie Clang nie może używać danych profilu, które generują -Wprofile-instr-out-of-date ostrzeżenie.

Użyj programu PGO

Korzystanie z programu PGO obejmuje te etapy:

  1. Utwórz bibliotekę/plik wykonywalny z instrumentacją, uzyskując -fprofile-generate do kompilatora i tagu łączącego.
  2. Zbieraj profile, uruchamiając reprezentatywne zadanie w instrumentowany plik binarny.
  3. Przetwarzanie profili za pomocą narzędzia llvm-profdata. (Szczegółowe informacje znajdziesz w artykule Obsługa modeli LLVM plików profilu).
  4. Użyj profili, aby zastosować PGO, przechodząc -fprofile-use=<>.profdata do kompilatora oraz tag łączący.

W przypadku programu PGO na Androidzie profile należy gromadzić offline i się odprawiać. jednocześnie z kodem, aby kompilacje były powtarzalne. Profile mogą być wykorzystywane jako kod ewoluuje, ale należy go okresowo generować (lub gdy ostrzeże Clang o ostrzeżeniach że profile są nieaktualne).

Zbieraj profile

Clang może korzystać z profili zebranych przez przeprowadzanie testów porównawczych za pomocą z instrumentowaną kompilację biblioteki lub przez próbkowanie liczników sprzętowych, gdy test porównawczy. Obecnie Android nie obsługuje korzystania z modelu opartego na próbkowaniu kolekcji profili, musisz więc zbierać profile przy użyciu sylwetka:

  1. Określ analizę porównawczą i zbiór bibliotek wspólnie używanych tej analizy porównawczej.
  2. Dodaj usługi pgo do testu porównawczego i biblioteki (szczegóły poniżej).
  3. tworzenie kompilacji na Androida przy użyciu z instrumentowanej kopii tych bibliotek; przy użyciu:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark to obiekt zastępczy, który identyfikuje zbiór bibliotek skonfigurowanych podczas kompilacji. Rzeczywisty przedstawiciel (i ewentualnie inny plik wykonywalny, który łączy się z biblioteką analizowana) nie są związane konkretnie z programem organizacji non-profit i są wykraczające poza zakres tego dokument.

  1. Flash lub synchronizuj kompilację instrumentalną na urządzeniu.
  2. Uruchom test porównawczy, aby zebrać profile.
  3. Użyj narzędzia llvm-profdata (opisane poniżej), aby po przetworzeniu profili i przygotować je do sprawdzenia w źródle drzewo.

Używaj profili podczas kompilacji

Sprawdź profile w aplikacji toolchain/pgo-profiles na Androidzie drzewo. Nazwa powinna być zgodna z nazwą w polu Usługa podrzędna profile_file usługi pgo dla do biblioteki. System kompilacji automatycznie przekazuje plik profilu do Clang. przy tworzeniu biblioteki. ANDROID_PGO_DISABLE_PROFILE_USE zmienną środowiskową można ustawić na true, aby tymczasowo wyłączyć usługę PGO i mierzyć jej skuteczność.

Aby określić dodatkowe katalogi profili konkretnych usług, dołącz je do: PGO_ADDITIONAL_PROFILE_DIRECTORIES utwórz zmienną w BoardConfig.mk Jeśli określono dodatkowe ścieżki, profile w te ścieżki zastępują ścieżki ścieżki toolchain/pgo-profiles.

Podczas generowania obrazu wersji za pomocą celu dist w celu make, system kompilacji zapisuje nazwy brakujących plików profilu do: $DIST_DIR/pgo_profile_file_missing.txt. Możesz to sprawdzić aby sprawdzić, które pliki profilu zostały przypadkowo usunięte (które dyskretnie wyłącza PGO).

Włącz PGO w plikach Android.bp

Aby włączyć PGO w plikach Android.bp dla modułów natywnych, po prostu określ właściwość pgo. Ta usługa ma: usług podrzędnych:

Usługa Opis
instrumentation Ustaw jako true dla PGO przy użyciu instrumentacji. Wartość domyślna to false
sampling Ustaw jako true dla PGO z wykorzystaniem próbkowania. Wartość domyślna to false
benchmarks Lista ciągów znaków. Ten moduł służy do profilowania, jeśli jakaś analiza porównawcza na liście jest określona w kompilacji ANDROID_PGO_INSTRUMENT .
profile_file Plik profilu (względem pliku toolchain/pgo-profile) do użycia z PGO. Kompilacja ostrzega, że ten plik nie istnieje, przez dodanie plik do: $DIST_DIR/pgo_profile_file_missing.txt chyba że właściwość enable_profile_use jest ustawiona na false LUB Zmienna kompilacji ANDROID_PGO_NO_PROFILE_USE jest ustawiona na true.
enable_profile_use Ustaw jako false, jeśli profili nie należy używać w tym czasie tworzyć. Można jej używać podczas wczytywania, aby włączyć zbieranie profili lub: tymczasowo wyłączyć PGO. Wartość domyślna to true.
cflags Lista dodatkowych flag, które mają być używane podczas zinstrumentowanej kompilacji.

Przykład modułu z funkcją 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",
    }
}

Jeśli testy porównawcze benchmark1 i benchmark2 reprezentatywne zachowanie dla bibliotek libstatic1, libstatic2, lub libshared1, pgo mogą też zawierać testy porównawcze. Moduł defaults w aplikacji Android.bp może zawierać wspólny pgo dla zbioru bibliotek w celu uniknięcia powtarzania te same zasady kompilacji dla kilku modułów.

Aby wybrać różne pliki profilu lub selektywnie wyłączyć PGO dla architektura, określ profile_file, enable_profile_use i cflags właściwości na i architekturą. Przykład (z docelową architekturą w pogrubienie):

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",
              }
         }
    }
}

Aby rozwiązać problemy z odwołaniami do biblioteki środowiska wykonawczego profilowania podczas profilowanie oparte na narzędziach, przekaż flagę kompilacji -fprofile-generate. Biblioteki statyczne z programem PGO, wszystkimi bibliotekami udostępnionymi oraz wszelkimi plikami binarnymi zależnymi bezpośrednio od klucza biblioteka statyczna musi być również dostosowana do PGO. Jednak takie udostępnione biblioteki lub pliki wykonywalne nie muszą używać profili PGO. Właściwość enable_profile_use można ustawić na false. Oprócz tego ograniczenia można stosować PGO do dowolnej biblioteki statycznej, lub wykonywalny.

Obsługuj pliki profilu LLVM

Wykonanie biblioteki zinstrumentowanej lub pliku wykonywalnego powoduje wygenerowanie pliku profilu o nazwie default_unique_id_0.profraw w /data/local/tmp (gdzie unique_id to który jest unikalny dla tej biblioteki). Jeśli ten plik już istnieje, środowisko wykonawcze profilowania łączy podczas pisania nowy profil ze starym profile. Pamiętaj, że aplikacja /data/local/tmp nie jest dostępna dla aplikacji programistów, powinni korzystać z jakiegoś elementu /storage/emulated/0/Android/data/packagename/files. Aby zmienić lokalizację pliku profilu, ustaw LLVM_PROFILE_FILE zmiennej środowiskowej w czasie działania.

llvm-profdata za pomocą tego narzędzia do przekonwertowania pliku .profraw (i być może scal kilka plików typu .profraw) w jeden .profdata plik:

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

Następnie będzie można zameldować się w źródle profile.profdata drzewo do użytku podczas kompilacji.

Jeśli podczas testu porównawczego zostanie wczytanych wiele zinstrumentowanych plików binarnych/bibliotek, każda biblioteka generuje oddzielny plik .profraw z osobnym unikalny identyfikator. Zwykle wszystkie te pliki można scalić w jeden .profdata i używany w kompilacji PGO. Gdy biblioteka jest testowana w innym teście porównawczym, należy zoptymalizować tę bibliotekę przy użyciu profili z obu tych źródeł. W takiej sytuacji show opcja llvm-profdata jest przydatna:

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

Aby zmapować identyfikator Unique_id na poszczególne biblioteki, przeszukaj show dane wyjściowe dla każdego parametru Unique_id dla nazwy funkcji, która który jest dostępny tylko w bibliotece.

Studium przypadku: PGO dla ART

Studium przypadku przedstawia ART jako przykład, z którym można się utożsamiać. nie jest to jednak dokładny opis faktycznego zestawu bibliotek profilowanych na potrzeby ART lub między ich współzależnościami.

Kompilator dex2oat z wyprzedzeniem w ART zależy od libart-compiler.so, która z kolei zależy od libart.so Środowisko wykonawcze ART jest implementowane głównie libart.so Kompilator i środowisko wykonawcze będą testów porównawczych różne:

Benchmark Biblioteki profilowe
dex2oat dex2oat (plik wykonywalny), libart-compiler.so, libart.so
art_runtime libart.so
  1. Dodaj do tabeli dex2oat następującą właściwość pgo, libart-compiler.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Dodaj do libart.so tę właściwość pgo:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Utwórz kompilacje instrumentalne na potrzeby platformy dex2oat i Testy porównawcze art_runtime za pomocą:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Możesz też utworzyć jedną instrumentowaną kompilację ze wszystkimi bibliotekami z instrumentacją wykorzystującą:

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

    Drugie polecenie tworzy wszystkie moduły obsługujące PGO dla: profilowanie.

  5. Przeprowadź test porównawczy: dex2oat i art_runtime, aby uzyskać:
    • 3 pliki (.profraw) z: dex2oat (dex2oat_exe.profdata, dex2oat_libart-compiler.profdata i dexeoat_libart.profdata), zidentyfikowano za pomocą metody opisane w sekcji Obsługa profilu LLVM .
    • Jeden art_runtime_libart.profdata.
  6. Wygeneruj wspólny plik profdata dla pliku wykonywalnego dex2oat i libart-compiler.so za pomocą:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. Uzyskaj profil libart.so, łącząc profile wyliczamy te 2 testy porównawcze:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    Nieprzetworzone liczniki zdarzeń libart.so z 2 profili mogą być są rozbieżne, ponieważ punkty odniesienia różnią się liczbą przypadków testowych przez okres, w którym są wyświetlane. W takim przypadku można użyć scalania ważonego:

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

    Powyższe polecenie przypisuje do profilu podwójną wagę z dex2oat Rzeczywista waga powinna być określona na podstawie domeny lub eksperymentowania.

  8. Sprawdź pliki profilu dex2oat.profdata i libart.profdata do: toolchain/pgo-profiles na używanych podczas kompilacji.