Usar a otimização guiada por perfil

O sistema de build do Android 13 e versões anteriores é compatível com o uso do guia de perfil do Clang otimização (PGO, na sigla em inglês) em módulos Android nativos que têm o build blueprint regras de firewall. Esta página descreve a PGO do Clang, como gerar e atualizar continuamente perfis usados para PGO e como integrá-la ao sistema de build (com o caso de uso).

Observação: este documento descreve o uso da PGO na plataforma Android. Para saber como usar PGO em um app Android, acesse esta página.

Sobre o Clang PGO

O Clang pode realizar a otimização guiada pelo perfil usando dois tipos de perfis:

  • Perfis baseados em instrumentação são gerados a partir de uma de destino instrumentado. Esses perfis são detalhados e impõem um alto o overhead do ambiente de execução.
  • Perfis baseados em amostragem são normalmente produzidos por contadores de hardware de amostragem. Eles impõem uma baixa sobrecarga no tempo de execução e podem ser coletados sem qualquer instrumentação ou modificação no binário. Eles são menos detalhados do que os baseados em instrumentação.

Todos os perfis devem ser gerados a partir de uma carga de trabalho representativa que exercita o comportamento típico do aplicativo. Embora o Clang ofereça suporte a Baseado em AST (-fprofile-instr-generate) e baseado em IR de LLVM (-fprofile-generate), o Android aceita apenas LLVM IR baseado em e PGO com base em instrumentação.

As seguintes sinalizações são necessárias para criar a coleta de perfis:

  • -fprofile-generate para instrumentação baseada em IR. Com este a opção de back-end usa uma abordagem de árvore de extensão mínima ponderada para reduzir o número de pontos de instrumentação e otimizar o posicionamento para bordas de baixo peso (use essa opção também para a etapa de vinculação). O Clang automaticamente o ambiente de execução de criação de perfil (libclang_rt.profile-arch-android.a) ao vinculador. Essa biblioteca contém rotinas para gravar os perfis no disco durante o programa saída.
  • -gline-tables-only para coleta de perfis com base em amostragem para gerar o mínimo de informações de depuração.

Um perfil pode ser usado para PGO usando -fprofile-use=pathname ou -fprofile-sample-use=pathname para base em instrumentação e perfis baseados em amostragem, respectivamente.

Observação:à medida que as alterações são feitas no código, se o Clang não conseguir use os dados de perfil que ela gera Aviso de -Wprofile-instr-out-of-date.

Usar PGO

O uso da PGO envolve as seguintes etapas:

  1. Criar a biblioteca/executável com instrumentação transmitindo -fprofile-generate ao compilador e ao vinculador.
  2. Colete perfis executando uma carga de trabalho representativa no binário instrumentado.
  3. Faça o pós-processamento dos perfis usando o utilitário llvm-profdata. (para obter detalhes, consulte Como lidar com LLVM arquivos de perfil).
  4. Use os perfis para aplicar a PGO transmitindo -fprofile-use=<>.profdata ao compilador e vinculador.

Para PGO no Android, os perfis precisam ser coletados off-line e verificados junto com o código para garantir builds reproduzíveis. Os perfis podem ser usados como o código evolui, mas precisa ser gerado novamente periodicamente (ou sempre que o Clang avisar se os perfis estão desatualizados).

Coletar perfis

O Clang pode usar perfis coletados ao executar comparações usando uma criação instrumentada da biblioteca ou por amostragem de contadores de hardware quando o comparativo de mercado é executado. No momento, o Android não oferece suporte ao uso de modelos coleta de perfis, portanto, você precisa coletar perfis usando um versão:

  1. Identificar um comparativo e o conjunto de bibliotecas usado coletivamente por para esse comparativo de mercado.
  2. Adicionar propriedades pgo à comparação e às bibliotecas (detalhes) abaixo).
  3. Produza um build do Android com uma cópia instrumentada dessas bibliotecas usando:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark é um marcador de posição que identifica de bibliotecas instrumentadas durante o build. O representante real entradas (e possivelmente outro executável vinculado a uma biblioteca comparadas) não são específicas da PGO e estão fora do escopo dessa documento.

  1. Atualizar ou sincronizar o build instrumentado em um dispositivo
  2. Execute a comparação para coletar perfis.
  3. Use a ferramenta llvm-profdata (discutida abaixo) para fazer o pós-processamento dos perfis e prepará-los para serem verificados na origem. árvore.

Usar perfis durante o build

Verificar os perfis no toolchain/pgo-profiles em um app Android árvore. O nome deve corresponder ao especificado no profile_file subpropriedade da propriedade pgo para da biblioteca. O sistema de build transmite automaticamente o arquivo de perfil para o Clang ao criar a biblioteca. O ANDROID_PGO_DISABLE_PROFILE_USE variável de ambiente pode ser definida como true para desativar temporariamente a PGO e medir o benefício de performance.

Para especificar mais diretórios de perfil específicos do produto, anexe-os ao a variável de criação PGO_ADDITIONAL_PROFILE_DIRECTORIES em uma BoardConfig.mk. Se caminhos adicionais forem especificados, os perfis em Esses caminhos substituem os de toolchain/pgo-profiles.

Ao gerar uma imagem de lançamento usando o destino dist para make, o sistema de build grava os nomes dos arquivos de perfil ausentes para $DIST_DIR/pgo_profile_file_missing.txt. Você pode verificar isso para ver quais arquivos de perfil foram acidentalmente descartados (que silenciosamente desativa a PGO).

Ativar PGO em arquivos Android.bp

Para ativar a PGO em arquivos Android.bp para módulos nativos, basta fazer o seguinte: especifique a propriedade pgo. Essa propriedade tem o seguinte subpropriedades:

Propriedade Descrição
instrumentation Defina como true para PGO usando a instrumentação. O padrão é false:
sampling Defina como true para PGO usando a amostragem. O padrão é false:
benchmarks Lista de strings. Esse módulo foi criado para criação de perfil em caso de na lista é especificado no build ANDROID_PGO_INSTRUMENT é a melhor opção.
profile_file Arquivo de perfil (relativo a toolchain/pgo-profile) a ser usado com a PGO. O build avisa que o arquivo não existe ao adicionar este arquivo em $DIST_DIR/pgo_profile_file_missing.txt a menos que a propriedade enable_profile_use esteja definida como false OU o A variável de build ANDROID_PGO_NO_PROFILE_USE está definida como true.
enable_profile_use Defina como false se os perfis não puderem ser usados durante ser construído. Pode ser usado durante a inicialização para ativar a coleta de perfis ou para desativar temporariamente a PGO. O padrão é true.
cflags Lista de outras flags que podem ser usadas durante um build instrumentado.

Exemplo de um módulo com 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",
    }
}

Se os comparativos de mercado benchmark1 e benchmark2 para exercitar o comportamento representativo das bibliotecas libstatic1, libstatic2 ou libshared1, o pgo dessas bibliotecas também podem incluir as comparações. A O módulo defaults em Android.bp pode incluir uma chave comum especificação pgo para um conjunto de bibliotecas para evitar a repetição da as mesmas regras de build para vários módulos.

Para selecionar diferentes arquivos de perfil ou desativar seletivamente a PGO para um do Cloud, especifique o profile_file, enable_profile_use e cflags propriedades por do Terraform. Exemplo (com destino de arquitetura em negrito):

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

Para resolver referências à biblioteca de tempo de execução de criação de perfil durante a criação de perfil baseada em instrumentação, transmita a flag de build -fprofile-generate ao vinculador. Bibliotecas estáticas instrumentadas com PGO, todas as bibliotecas compartilhadas e qualquer binário que dependa diretamente da biblioteca estática também precisa ser instrumentada para PGO. No entanto, esses grupos bibliotecas ou executáveis não precisam usar perfis PGO, e os A propriedade enable_profile_use pode ser definida como false. Fora dessa restrição, é possível aplicar a PGO a qualquer biblioteca estática compartilhada. ou executável.

Processar arquivos de perfil LLVM

A execução de um executável ou biblioteca instrumentada produz um arquivo de perfil chamado default_unique_id_0.profraw em /data/local/tmp (em que unique_id é um hash numérico exclusivo dessa biblioteca). Se esse arquivo já existir, o tempo de execução da criação do perfil mescla o perfil novo com o antigo durante a gravação os perfis. Observe que /data/local/tmp não pode ser acessado pelo app desenvolvedores eles devem usar em algum lugar /storage/emulated/0/Android/data/packagename/files. Para mudar o local do arquivo de perfil, defina o LLVM_PROFILE_FILE variável de ambiente no ambiente de execução.

O llvm-profdata é usado para converter o arquivo .profraw (e possivelmente mesclar vários arquivos .profraw) em um .profdata arquivo:

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

profile.profdata pode ser verificado na origem para usar durante a criação.

Se vários binários/bibliotecas de instrumentação forem carregados durante uma comparação, cada biblioteca gera um arquivo .profraw separado com um arquivo um ID exclusivo. Normalmente, todos esses arquivos podem ser mesclados em um único .profdata e usado para o build da PGO. Nos casos em que uma biblioteca for exercida por outra comparação, essa biblioteca precisa ser otimizada usando dos dois comparativos de mercado. Nessa situação, o show de llvm-profdata é útil:

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

Para mapear unique_ids para bibliotecas individuais, pesquise o saída show para cada unique_id do nome de uma função que é exclusivo da biblioteca.

Estudo de caso: PGO for ART

O estudo de caso apresenta o ART como um exemplo relacionável: No entanto, não é uma descrição precisa do conjunto real de bibliotecas para o ART ou o as interdependências deles.

O compilador antecipado dex2oat no ART depende libart-compiler.so, que, por sua vez, depende libart.so O tempo de execução ART é implementado principalmente libart.so: Os comparativos de mercado do compilador e do ambiente de execução serão diferente:

Benchmark Bibliotecas com perfil
dex2oat dex2oat (executável), libart-compiler.so, libart.so
art_runtime libart.so
  1. Adicione a seguinte propriedade pgo a dex2oat: libart-compiler.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Adicione a seguinte propriedade pgo a libart.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Crie builds instrumentados para dex2oat e Comparativos de mercado do art_runtime usando:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Como alternativa, crie um único build instrumentado com todas as bibliotecas instrumentado usando:

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

    O segundo comando cria todos os módulos ativados para PGO para criação de perfis.

  5. Execute as comparações exercendo dex2oat e art_runtime para receber:
    • Três arquivos .profraw de dex2oat (dex2oat_exe.profdata, dex2oat_libart-compiler.profdata e dexeoat_libart.profdata), identificados usando o método descrito em Manuseio de perfil LLVM arquivos.
    • Um único art_runtime_libart.profdata.
  6. Produza um arquivo profdata comum para o executável dex2oat e libart-compiler.so usando:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. Mesclar os perfis para encontrar o libart.so dos dois comparativos de mercado:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    As contagens brutas para libart.so dos dois perfis podem ser discrepantes porque os comparativos de mercado diferem no número de casos de teste e no durante o qual eles são executados. Nesse caso, você pode usar uma mesclagem ponderada:

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

    O comando acima atribui o dobro do peso ao perfil da dex2oat: O peso real deve ser determinado com base no domínio ou experimentação.

  8. Verifique os arquivos de perfil dex2oat.profdata e libart.profdata em toolchain/pgo-profiles para durante o build.