- Explora a implementação de pipes Unix no Linux e métodos de otimização de programas de teste que escrevem e leem dados por meio de pipes
- O programa inicial tinha uma taxa de transferência de cerca de 3.5GiB/s, e isso foi melhorado em 20 vezes com várias otimizações
- Essas otimizações foram feitas por meio do profiling do programa com a ferramenta
perf do Linux
- O texto foi inspirado em um programa FizzBuzz otimizado que empurra saída para um pipe a uma velocidade de ~35GiB/s
- Aprofunda-se em como os pipes funcionam internamente, por que escrever e ler deles é lento, e como as system calls
vmsplice e splice podem melhorar o desempenho
- Discute como o uso de paginação no Linux e de huge pages pode levar a versões mais rápidas do programa
- A otimização final inclui substituir polling por um loop ocupado
- Os testes foram realizados em uma CPU Intel Skylake i7-8550U com Linux 5.17
- O texto explica em detalhe como a memória é composta por páginas, que são blocos de tamanho fixo, e como a CPU usa tabelas de páginas para traduzir endereços virtuais em endereços físicos
- O texto conclui com a observação de que mudar o programa para huge pages melhora o desempenho em cerca de 50%
- O texto discute o uso de huge pages na CPU e formas de reduzir falhas no Translation Lookaside Buffer (TLB), o que pode melhorar o desempenho
- O código do kernel assume que
struct page aponta para uma página de tamanho padrão da arquitetura atual. No caso de huge pages, a struct page "head" contém as informações sobre a página física real, enquanto as páginas "tail" consecutivas contêm apenas ponteiros para a página head
- Kernels recentes (após a versão 5.17) incluem um novo tipo,
struct folio, que identifica explicitamente a página head. Isso melhora o desempenho ao reduzir a necessidade de verificar em tempo de execução se uma struct page é head ou tail
- O texto discute o conceito de loop ocupado para evitar o custo de sincronização. A ideia é pedir que
vmsplice retorne quando não for possível escrever no pipe e ficar em loop ocupado até ele estar pronto. Isso pode trazer um ganho de 25% em desempenho, mas ao custo de ocupar totalmente um núcleo da CPU até que vmsplice fique pronto
- O autor resume os principais temas abordados: operações de cópia zero, buffers em anel, paginação e memória virtual, overhead de sincronização
- O autor também reconhece que há muitas outras opções e detalhes não discutidos no texto, seja por falta de relevância ou de interesse
- O texto foi bem recebido pelos leitores, que o consideraram útil e interessante
1 comentários
Comentários do Hacker News
vmsplice, que funciona como um mecanismo de mini memória compartilhada entre dois processosvmspliceexige tratamento cuidadoso dos buffers durante leitura e escrita, e embora seja complexo, pode ser eficientesplice()evmsplice(), que são consideradas difíceis de usar e pouco aproveitadas na maioria dos programasstdoutde um programa para ostdinde outro, tornando a operaçãozerocopyou, em situações menos otimizadas, um rápidoonecopyperf, destacando sua importância para o throughputcat,sed,awk,cut,grep,uniqejq