Compilação antecipada - Ahead-of-time compilation

Na ciência da computação, a compilação antecipada ( compilação AOT ) é o ato de compilar uma linguagem de programação (frequentemente) de nível superior em uma linguagem de nível (frequentemente) de nível inferior antes da execução de um programa, geralmente em tempo de construção, para reduza a quantidade de trabalho necessária a ser executada em tempo de execução .

Na maioria das vezes, está associado ao ato de compilar uma linguagem de programação de nível superior , como C ou C ++ , ou uma representação intermediária , como bytecode Java ou código .NET Framework Common Intermediate Language (CIL), em um código nativo (dependente do sistema) ) código de máquina para que o arquivo binário resultante possa ser executado nativamente, assim como um compilador nativo padrão . Quando usado neste contexto específico, geralmente é visto como o oposto da compilação just-in-time (JIT).

Falando de forma mais geral, as linguagens de destino de uma compilação AOT não são necessariamente específicas ao código de máquina nativo , mas são definidas de forma arbitrária. Alguns artigos acadêmicos usam essa palavra para significar o ato de compilar o bytecode Java para C ou o momento em que o pipeline de otimização é executado. Um projeto acadêmico usa esta palavra para significar o ato de pré-compilar JavaScript para um IR otimizado dependente da máquina para V8 (mecanismo JavaScript) e para um bytecode independente da máquina para JavaScriptCore . Algumas implementações de linguagem industrial (por exemplo, mecanismo JavaScript Closure e Hermes ) usam essa palavra para significar o ato de pré-compilar a linguagem de origem para o bytecode específico da VM. Angular (estrutura da web) usa essa palavra para significar a conversão de seu modelo HTML e TypeScript para JavaScript .

Na verdade, uma vez que toda compilação estática é tecnicamente executada com antecedência, esse texto específico é frequentemente usado para enfatizar algum tipo de vantagem de desempenho do ato de tal pré-compilação. O ato de compilar Java para bytecode Java é, portanto, raramente referido como AOT, pois geralmente é um requisito, não uma otimização.

Sobrecarga de tempo de execução reduzida

Algumas linguagens de programação com um tempo de execução de código gerenciado que podem ser compilados para uma representação intermediária, usam a compilação just-in-time (JIT). Isso, resumidamente, compila o código intermediário em código de máquina para uma execução nativa enquanto o código intermediário está em execução, o que pode diminuir o desempenho de um aplicativo. A compilação antecipada elimina a necessidade dessa etapa, ocorrendo antes da execução, e não durante a execução.

A compilação antecipada de linguagens digitadas dinamicamente para código de máquina nativo ou outro bytecode VM estático é possível apenas em um número limitado de casos. Por exemplo, o compilador AOT High Performance Erlang Project (HiPE) para a linguagem Erlang pode fazer isso por causa de técnicas avançadas de reconstrução de tipo estático e especulações de tipo.

Na maioria das situações com programas e bibliotecas totalmente compilados AOT, é possível eliminar uma fração útil de um ambiente de tempo de execução , economizando espaço em disco, memória, vida útil da bateria e tempos de inicialização (sem fase de aquecimento JIT), etc. Por causa disso, pode ser útil em dispositivos embarcados ou móveis.

Compromissos de desempenho

Os compiladores AOT podem realizar otimizações de código complexas e avançadas , que na maioria dos casos de JITing serão consideradas muito caras. Em contraste, AOT geralmente não pode realizar algumas otimizações possíveis no JIT, como otimização guiada por perfil de tempo de execução (PGO), propagação de pseudo- constante ou inlining de função virtual indireta . AOT deve compilar para uma arquitetura de destino, enquanto um JIT pode compilar o código para fazer o melhor uso da CPU real em que está sendo executado, mesmo anos após o lançamento do software.

Além disso, os compiladores JIT podem otimizar especulativamente o código quente fazendo suposições sobre o código. O código gerado pode ser desotimizado se uma suposição especulativa posteriormente se provar errada. Tal operação retarda o desempenho do software em execução até que o código seja otimizado novamente pela otimização adaptativa . Um compilador AOT não pode fazer tais suposições e precisa inferir o máximo de informações possível no momento da compilação. Ele precisa recorrer a um código menos especializado porque não pode saber quais tipos passarão por um método. Esses problemas podem ser atenuados por otimizações guiadas por perfil. Mas, mesmo nesse caso, o código gerado não pode ser adaptado dinamicamente ao perfil de tempo de execução em mudança, como faria um compilador JIT.

Trade-offs de armazenamento

Veja também

Referências

links externos