Executando verificação de segurança...
3

Bom, nesse caso não há muito o que uma linguagem de programação AOT possa fazer para competir com linguagens que usa JIT. Mas há casos e casos:

  1. Se seu programa precisa ser leve com pouco gasto de RAM e Memória: AOT
  2. Se seu programa for criado para iniciar super rápido e ser usado rapidamente: AOT

Em outros casos, não há problema nenhum em usar JIT sabendo que:

  1. Apesar do aumento de performance, o JIT vai consumir mais cpu e memória para otimizar o seu código em execução

  2. A inicialização de um processo com JIT é mais lento que a inicialização de um projeto AOT por conter estruturas adicionais para compilação in-runtime do projeto

Mas se seu código vai ficar por muito tempo vivo, de preferência continuamente executando alguma coisa então não tem nada de errado em usar JIT.

Inclusive o canal do Andreas Kling que eu citei em outro post, para lidar com o ladybird, seu webbrowser ele decidiu criar um interpretador javascript próprio chamado LibJS que contém um JIT próprio e você pode acompanhar por exemplo este Vídeo sobre ele prototipando um JIT

E voltando ao assunto principal, não tem com uma linguagem AOT competir com um JIT porque as abordagens são diferentes:

AOT: Passei uma vez pelo código e o binário vai ser justamente isso aqui x.
JIT: Tive que passar várias vezes pelo mesmo trecho de código então acho que posso otimizar isso aqui x.

Carregando publicação patrocinada...
2

AOT: Passei uma vez pelo código e o binário vai ser justamente isso aqui x.
JIT: Tive que passar várias vezes pelo mesmo trecho de código então acho que posso otimizar isso aqui x.

Valeu pelas dicas, vou assistir. Eu vejo o trade-off assim:

AOT: Não vai perder tempo durante o run-time compilando nada. Não precisa esquentar (warmup).
JIT: Vai perder tempo durante o run-time compilando os hot spots. Vai precisar de um tempo de warmup para peak performance.

Só que o JIT pode fazer otimizações muito mais agressivas que o AOT. Acho que o pessoal sempre achou que AOT com -O3 era a coisa mais rápida do mundo. Pelo testes que eu venho fazendo aí parece que perde muitas vezes para o JIT. Runtime information ajuda muito nas otimizações mais agressivas, principalmente no inlining. Sem saber os hotspots, o AOT vai acabar deixando de fazer inlining nas coisas mais importantes. Uma idéia que pensei aqui: por que os compiiladores de C++ não possuem alguma diretriz para forçar inlining de algum método no matter what? Ou tem isso e eu desconheço?

O que se faz é usar PGO (profiling information) that can be fed into the AOT compiler. Tanto o AOT quanto o JIT podem ter isso. Mas daí o JIT leva muita vantagem, porque se os HotSpots mudarem em tempo de execução ele pode se re-adaptar, ou seja, recompilar os novos hot spots. AOT não existe depois que o código começa a executar.

Na minha cabeça (posso estar errado) o problema é que se o código muda, daí vc tem que refazer o PGO para refletir o novo código. Se o código muda pouco no problem. Se muda muito aí complica.

Agora para concluir, minhas pesquisas com o PGO do GraalVM e da ZingVM (ReadyNow) mostraram uma melhorar de no máximo 50%. Ou seja, não chega perto do JIT em tempo de execução não. É uma ajuda, mas não é a solução para não precisar de JIT.

NOTE: PGO = Profile-guided optimizations

2

por que os compiiladores de C++ não possuem alguma diretriz para forçar inlining de algum método no matter what?

Forçar inline indiscriminadamente é impacta no cache de instruções e o aumento do tamanho do binário, pode acabar poluindo o cache de instruções (https://isocpp.org/wiki/faq/inline-functions#inline-and-perf).

Sobre os hotspots mudarem durante a execução, isso não costuma ser uma preocupação no contexto de C++, porque ela é geralmente escolhida para cenários onde sabemos que estamos lidando com rotinas CPU-bound e grandes volumes de dados. Nesses cenários, mesmo que surjam novas features, times experientes em C++ geralmente já estão espertos para identificar isso.

1

Forçar inline indiscriminadamente é impacta no cache de instruções e o aumento do tamanho do binário, pode acabar poluindo o cache de instruções

Sim, claro. Não estava sugerindo fazer inline de tudo. Isso obviamente é impraticável e é exatamente por isso que o JIT acaba levando vantagem. Minha sugestão foi:

O AOT não tem como saber os hot spots. O JIT tem, mas gasta tempo de runtime para descborir. Já o programador possui esse conhecimento, até melhor que o AOT e o JIT. Então ele (o programador) pegaria aqueles métodos que ele sabe que são quentes (hot) e anotaria eles com um @Inline para forçar que esses métodos, independente do tamanho deles, fossem inlined.

Por que o compilador de C++ ou Java não oferecem isso?