Meu palpite é que as dicas de previsão no nível de instruções da máquina são, na melhor das hipóteses, um ruído e, na pior das hipóteses, um prejuízo (bytes de instrução desperdiçados) na moderna arquitetura fora de ordem e de execução especulativa. Fazer isso seria como dizer à CPU para diminuir a velocidade - para parar de fazer as coisas já inteligentes que foi projetada para executar.
Em segundo lugar, o grau em que a previsão do ramo pode ser aprimorada depende da causa da imprevisibilidade e da facilidade com que se pode medir os efeitos de desempenho ou observar a tendência do ramo.
No entanto, acho que o pacote existente de truques de otimização JIT já pode melhorar a previsão de ramificações até certo ponto, mesmo sem a ajuda dos contadores de erros de predição de ramificação da CPU.
Apenas um exemplo de código muito simples:
public void repeatHistory(int value)
{
if (value == 1492)
{
landing();
}
else if (value == 1776)
{
ratifying();
}
}
Supõe-se que isso repeatHistory
seja chamado muitas vezes. Quando o monitor de desempenho baseado em amostragem analisa as estatísticas da pilha de chamadas, ele pode descobrir que, por qualquer motivo, a repeatHistory()
chamada ratifying()
ocorre com mais frequência do que a chamada anterior landing()
. Com base nesta observação, a próxima passagem da geração de código JIT para o repeatHistory
método levará isso em consideração e executará uma ou mais otimizações:
- Mova a verificação para
(value == 1776)
antes da verificação para(value == 1492)
- Tente incorporar o
ratifying()
método na ramificação emrepeatHistory()
- Se
repeatHistory()
for chamado de outro loop, tente desenrolar o loop ou incline o repeatHistory()
método nesse loop.
- E muitos outros.
Depois de aplicar uma otimização, geralmente é necessário analisar novamente para ver se mais otimizações podem ser aplicadas, porque uma bem-sucedida geralmente abre as portas para mais oportunidades.