2 pontos por GN⁺ 3 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • OxCaml, um superconjunto de OCaml da Jane Street, permite declarar ao compilador com [@zero_alloc] a proibição de alocação no heap em toda a árvore de chamadas de uma função
  • Se ocorrer uma alocação no caminho de chamada declarado, isso aparece imediatamente como falha de compilação, o que ajuda a bloquear regressões mais rápido do que descobri-las depois com um profiler
  • Em C, C++, Java, Go, C#, Rust, Zig, OCaml e outras, normalmente a abordagem principal é encontrar e reduzir alocações em hot paths com um profiler
  • Código de hot path pode voltar a gerar alocações com pequenas mudanças, então, se o contexto da otimização original for esquecido, a mesma investigação acaba sendo repetida
  • Convenções de passagem de allocator em Zig ou em parte do Rust moderno também ajudam, mas uma verificação do compilador é uma proteção mais direta do que uma convenção

O que [@zero_alloc] muda na gestão de alocações

  • OxCaml é um superconjunto de OCaml da Jane Street e oferece suporte para afirmar que uma função não faz alocações no heap
  • Ao adicionar [@zero_alloc] a uma função, o compilador verifica não só essa função, mas toda a árvore de chamadas abaixo dela quanto a alocações no heap
  • Se houver uma alocação dentro da árvore de chamadas, o build falha e o compilador informa a ocorrência da alocação
  • Pode ser possível criar verificações parecidas com análise estática, mas, entre linguagens mainstream, é raro ver esse tipo de recurso embutido no próprio compilador com base em resumos gerados

Diferença em relação à abordagem centrada em profiler

  • Em outras linguagens, o normal é encontrar alocações com um profiler e depois remover ou reduzir essas alocações, especialmente dentro de loops executados milhões de vezes
  • C, C++, Java, Go, C#, Rust, Zig e OCaml são listadas como exemplos dessa abordagem centrada em profiler
  • Mudar apenas uma linha em um hot path pode reintroduzir alocações, e então é preciso voltar ao profiler para descobrir a causa
  • Em Zig ou em parte do Rust moderno, é possível reduzir regressões evitando passar o allocator para as funções, mas isso depende de convenções
  • A diferença de [@zero_alloc] é que, em vez de análise posterior ou regras de equipe, o compilador bloqueia regressões de alocação no momento do build

1 comentários

 
GN⁺ 3 시간 전
Comentários no Lobste.rs
  • Entendi que o motivo de passar um allocator como argumento de função em Zig é impedir que funções que não recebem um allocator como argumento possam fazer alocações no heap; será que está certo?
    Se a afirmação de que “convenções podem ser ignoradas” estiver realmente correta, parece diferente da intenção

    • Sim, no fim é apenas uma convenção.
      Mesmo dentro de uma função, é possível criar um novo allocator, assim como fora dela
  • gift link: https://theconsensus.dev/p/2026/…

  • Usar apenas core em Rust também é uma forma de evitar alocações

    • “Evitar alocações” é só parte da história.
      Essa abordagem acaba sendo mais próxima de “controle suas dependências” ou “verifique manualmente todo o grafo de chamadas”.
      O foco do artigo está em como uma ferramenta como o compilador impõe estaticamente certas propriedades e oferece um fluxo de trabalho para encontrar de forma produtiva os pontos em que essas propriedades são violadas
  • D tem @nogc, e depois disso a questão é usar apenas abstrações diretamente controláveis que tenham padrões de alocação claros

  • Como perdemos a capacidade de criar títulos de artigos descritivos, vale acrescentar: o ponto central é um recurso em que você marca uma função com [@zero_alloc] e o compilador rejeita o programa se a árvore de chamadas dessa função tocar no heap

  • Fico curioso se esse tipo de abordagem também poderia ser aplicada a várias condições como “não lança exceções nem entra em panic”, “sem locks” e “sempre termina”