Abseil Performance Hints (Jeff Dean & Sanjay Ghemawat)
1. Visão geral
Este documento reúne princípios gerais e técnicas específicas de ajuste de desempenho de software que o Google considera importantes desde seus primeiros dias. Em vez de ajustes em sistemas distribuídos ou hardware de ML, o foco está na otimização de desempenho sob a perspectiva de um único binário.
2. Principais pontos
Forma de pensar sobre desempenho (Thinking about performance)
- Mal-entendido sobre “a otimização prematura é a raiz de todo mal”: esse ditado significa ignorar 97% das pequenas eficiências, não perder até mesmo as oportunidades críticas dos 3% restantes.
- Importância de pequenas melhorias: um ganho de velocidade de cerca de 12% nunca é trivial do ponto de vista de engenharia e é essencial para programas de alta qualidade.
- Escolhas iniciais: a abordagem de “fazer algo simples primeiro e otimizar depois” muitas vezes leva a uma degradação geral de desempenho (Flat Profile), o que dificulta melhorias. Se isso não prejudicar muito a legibilidade ou a complexidade, é melhor escolher desde o início uma alternativa mais rápida (por exemplo,
absl::InlinedVectorem vez destd::vector).
Estimativa (Estimation)
- Intuição e cálculo: ao escrever código, é importante ter uma noção prévia do impacto no desempenho.
- Cálculos rápidos de guardanapo: antes de implementar, estime de forma aproximada o custo de recursos. (Ex.: referência ao cache L1 0.5ns, lock de mutex 15ns, leitura em SSD 20µs etc., calculando o desempenho esperado com base no custo de operações básicas)
Medição (Measurement)
- Profiling: medições eficazes são a ferramenta mais importante. É preciso usar
pprof,perfetc. para identificar os gargalos reais. - Dicas: teste com o binário de produção com flags de otimização aplicadas e escreva microbenchmarks para verificar o impacto das mudanças.
Lidando com Flat Profile
- Quando não há um gargalo claro: se o perfil de CPU vier achatado, uma estratégia eficaz é acumular pequenas otimizações de 1% ao longo de todo o sistema.
- Melhorias estruturais: vale considerar reestruturar loops no topo da pilha de chamadas ou mudar as estruturas de dados.
Exemplos de técnicas concretas
- Melhoria de algoritmos: substitua a lógica de detecção de ciclos ou detecção de deadlock por algoritmos mais eficientes (por exemplo, baseados em ordenação topológica) para garantir velocidade e escalabilidade.
- Otimização da representação em memória: compacte estruturas de dados acessadas com frequência ou ajuste o layout de memória (reordenação de campos, redução de padding) para aumentar a eficiência de cache e reduzir o tráfego no barramento de memória.
1 comentários
Uau..