O sistema de build do Android 13 e versões anteriores oferece suporte ao uso da otimização guiada por perfil (PGO, na sigla em inglês) do Clang em módulos Android nativos que têm regras de build de diagrama. Esta página descreve a PGO do Clang, como gerar e atualizar continuamente os perfis usados para a PGO e como integrar a PGO ao sistema de build (com caso de uso).
Observação: este documento descreve o uso da PGO na plataforma Android. Para saber como usar a PGO em um app Android, acesse esta página.
Sobre a PGO do Clang
O Clang pode realizar a otimização guiada por perfil usando dois tipos de perfil:
- Os perfis baseados em instrumentação são gerados a partir de um programa de destino instrumentado. Esses perfis são detalhados e impõem uma sobrecarga de execução alta.
- Os perfis baseados em amostragem geralmente são produzidos por amostragem de contadores de hardware. Eles impõem uma sobrecarga de execução baixa e podem ser coletados sem nenhuma instrumentação ou modificação no binário. Eles são menos detalhados do que os perfis baseados em instrumentação.
Todos os perfis precisam ser gerados a partir de uma carga de trabalho representativa que
  exerça o comportamento típico do app. Embora o Clang ofereça suporte a
  AST (-fprofile-instr-generate) e LLVM IR
  (-fprofile-generate)), o Android oferece suporte apenas a LLVM IR para
  PGO baseada em instrumentação.
As flags a seguir são necessárias para criar a coleta de perfis:
- -fprofile-generatepara instrumentação baseada em IR. Com essa opção, o back-end usa uma abordagem de árvore mínima ponderada para reduzir o número de pontos de instrumentação e otimizar a posição deles para bordas de baixo peso. Use essa opção também para a etapa de vinculação. O driver Clang transmite automaticamente o ambiente de execução de perfil (- libclang_rt.profile-arch-android.a) ao vinculador. Essa biblioteca contém rotinas para gravar os perfis no disco ao sair do programa.
- -gline-tables-onlypara a coleta de perfis baseada em amostragem para gerar informações mínimas de depuração.
Um perfil pode ser usado para a PGO usando
  -fprofile-use=pathname ou
  -fprofile-sample-use=pathname para perfis baseados em instrumentação
  e amostragem, respectivamente.
Observação:à medida que as mudanças são feitas no código, se o Clang não puder
  mais usar os dados do perfil, ele gerará um
  aviso -Wprofile-instr-out-of-date.
Usar o PGO
O uso da PGO envolve as seguintes etapas:
- Crie a biblioteca/executável com instrumentação transmitindo
    -fprofile-generateao compilador e ao vinculador.
- Colete perfis executando uma carga de trabalho representativa no binário instrumentado.
- Faça o pós-processamento dos perfis usando o utilitário llvm-profdata. Para mais detalhes, consulte Como lidar com arquivos de perfil LLVM.
- Use os perfis para aplicar a PGO transmitindo
    -fprofile-use=<>.profdatapara o compilador e o vinculador.
Para o 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 à medida que o código evolui, mas precisam ser regenerados periodicamente (ou sempre que o Clang avisar que os perfis estão desatualizados).
Coletar perfis
O Clang pode usar perfis coletados executando comparativos de mercado usando um build instrumentado da biblioteca ou amostrando contadores de hardware quando o comparativo de mercado é executado. No momento, o Android não oferece suporte à coleta de perfis baseada em amostragem. Portanto, é necessário coletar perfis usando um build instrumentado:
- Identifique um comparativo de mercado e o conjunto de bibliotecas exercido coletivamente por esse comparativo.
- Adicione propriedades pgoao comparativo de mercado e às bibliotecas (detalhes abaixo).
- 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 a
  coleção de bibliotecas instrumentadas durante o build. As entradas
  de exemplo reais (e possivelmente outro executável vinculado a uma biblioteca
  sendo comparada) não são específicas para a PGO e estão fora do escopo deste
  documento.
- Faça a atualização ou a sincronização do build instrumentado em um dispositivo.
- Execute o comparativo para coletar perfis.
- Use a ferramenta llvm-profdata(discutida abaixo) para processar os perfis e deixá-los prontos para serem verificados na árvore de origem.
Usar perfis durante o build
Verifique os perfis em toolchain/pgo-profiles em uma árvore
  do Android. O nome precisa corresponder ao especificado na
  subpropriedade profile_file da propriedade pgo da
  biblioteca. O sistema de build transmite automaticamente o arquivo de perfil para o Clang
  ao criar a biblioteca. A variável de ambiente ANDROID_PGO_DISABLE_PROFILE_USE
  pode ser definida como true para
  desativar temporariamente o PGO e medir o benefício de desempenho.
Para especificar outros diretórios de perfil específicos do produto, anexe-os à
  variável de make PGO_ADDITIONAL_PROFILE_DIRECTORIES em um
  BoardConfig.mk. Se outros caminhos forem especificados, os perfis nesses caminhos vão substituir 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
  em $DIST_DIR/pgo_profile_file_missing.txt. Você pode verificar esse
  arquivo para saber quais arquivos de perfil foram descartados acidentalmente (o que desativa silenciosamente
  o PGO).
Ativar o PGO em arquivos Android.bp
Para ativar a PGO em arquivos Android.bp para módulos nativos, basta
  especificar a propriedade pgo. Essa propriedade tem as seguintes
  subatributos:
| Propriedade | Descrição | 
|---|---|
| instrumentation | Definido como truepara PGO usando instrumentação. O padrão éfalse. | 
| sampling | Defina como truepara PGO usando amostragem. O padrão éfalse. | 
| benchmarks | Lista de strings. Esse módulo é criado para criar perfis se qualquer comparativo
      na lista for especificado na opção de build ANDROID_PGO_INSTRUMENT. | 
| profile_file | Arquivo de perfil (relativo a toolchain/pgo-profile) para usar
      com a PGO. O build avisa que esse arquivo não existe adicionando-o a$DIST_DIR/pgo_profile_file_missing.txta menos que a propriedadeenable_profile_useseja definida comofalseOU a
      variável de buildANDROID_PGO_NO_PROFILE_USEseja definida comotrue. | 
| enable_profile_use | Defina como falsese os perfis não forem usados durante o
      build. Pode ser usado durante o bootstrap para ativar a coleta de perfil ou
      desativar temporariamente o PGO. O padrão étrue. | 
| cflags | Lista de flags adicionais a serem 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
  exercerem um comportamento representativo para as bibliotecas libstatic1,
  libstatic2 ou libshared1, a propriedade pgo
  dessas bibliotecas também poderá incluir os comparativos de mercado. O
  módulo defaults em Android.bp pode incluir uma especificação
  pgo comum para um conjunto de bibliotecas para evitar a repetição das
  mesmas regras de build para vários módulos.
Para selecionar diferentes arquivos de perfil ou desativar seletivamente a PGO para uma
  arquitetura, especifique as propriedades profile_file,
  enable_profile_use e cflags por
  arquitetura. Exemplo (com o destino da 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 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. As bibliotecas estáticas instrumentadas
  com PGO, todas as bibliotecas compartilhadas e qualquer binário que dependa diretamente da
  biblioteca estática também precisam ser instrumentadas para PGO. No entanto, essas bibliotecas
  compartilhadas ou executáveis não precisam usar perfis de PGO, e a propriedade
  enable_profile_use delas 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 uma biblioteca ou um executável instrumentado produz um arquivo de perfil
  chamado default_unique_id_0.profraw em
  /data/local/tmp, em que unique_id é um
  hash numérico exclusivo para essa biblioteca. Se esse arquivo já existir,
  o ambiente de execução de criação de perfil vai mesclar o novo perfil com o antigo ao gravar
  os perfis. /data/local/tmp não é acessível para desenvolvedores
  de apps. Eles precisam usar algo como
  /storage/emulated/0/Android/data/packagename/files.
  Para mudar o local do arquivo de perfil, defina a variável de ambiente LLVM_PROFILE_FILE
  no momento da execução.
O utilitário llvm-profdata
  é usado para converter o arquivo .profraw (e possivelmente
  mesclar vários arquivos .profraw) em um arquivo
  .profdata:
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
O profile.profdata pode ser verificado na árvore
  de origem para uso durante o build.
Se vários binários/bibliotecas instrumentados forem carregados durante um comparativo de mercado,
  cada biblioteca vai gerar um arquivo .profraw separado com um ID exclusivo. Normalmente, todos esses arquivos podem ser mesclados em um único arquivo
  .profdata e usados para o build de PGO. Nos casos em que uma biblioteca
  é usada por outro comparativo de mercado, ela precisa ser otimizada usando
  perfis de ambos os comparativos. Nessa situação, a opçã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 a
  saída show para cada unique_id para um nome de função que
  seja exclusivo da biblioteca.
Estudo de caso: PGO para ART
O estudo de caso apresenta o ART como um exemplo relacionado, mas não é uma descrição precisa do conjunto real de bibliotecas com perfil para o ART ou suas interdependências.
O compilador dex2oat antes do tempo no ART depende de
  libart-compiler.so, que, por sua vez, depende de
  libart.so. O ambiente de execução do ART é implementado principalmente em
  libart.so. Os comparativos de mercado para o compilador e o ambiente de execução serão
  diferentes:
| Benchmark | Bibliotecas com perfil | 
|---|---|
| dex2oat | dex2oat(executável),libart-compiler.so,libart.so | 
| art_runtime | libart.so | 
- Adicione a seguinte propriedade pgoadex2oat,libart-compiler.so:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", }
- Adicione a seguinte propriedade pgoalibart.so:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", }
- Crie builds instrumentados para os comparativos de mercado dex2oateart_runtimeusando:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime
- Execute as comparações usando dex2oateart_runtimepara receber:- Três arquivos .profrawdedex2oat(dex2oat_exe.profdata,dex2oat_libart-compiler.profdataedexeoat_libart.profdata), identificados usando o método descrito em Como gerenciar arquivos de perfil LLVM.
- Um único art_runtime_libart.profdata.
 
- Três arquivos 
- Produza um arquivo profdata comum para o executável dex2oatelibart-compiler.sousando:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata
- Para extrair o perfil de libart.so, mescle os perfis das duas comparações:llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdataAs contagens brutas de libart.sodos dois perfis podem ser diferentes porque os comparativos variam no número de casos de teste e na duração de execução. Nesse caso, é possível usar uma mesclagem ponderada:llvm-profdata merge -output=libart.profdata \ -weighted-input=2,dex2oat_libart.profdata \ -weighted-input=1,art_runtime_libart.profdataO comando acima atribui o dobro do peso ao perfil de dex2oat. O peso real precisa ser determinado com base no conhecimento de domínio ou na experimentação.
- Verifique os arquivos de perfil dex2oat.profdataelibart.profdataemtoolchain/pgo-profilespara uso durante o build.
Como alternativa, crie um único build instrumentado com todas as bibliotecas instrumentadas usando:
    make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
    (or)
    make ANDROID_PGO_INSTRUMENT=ALLO segundo comando cria todos os módulos ativados para PGO para criação de perfil.
