Geração de código nativo

Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Com o suporte do Luau para geração de código nativa, os scripts do lado do servidor em sua experiência podem ser compilados diretamente nas instruções de código da máquina que as CPUs realizam, em vez do bytecode regular que a VM do Luau opera. Esta característica pode ser usada para melhorar a velocidade de implementação de alguns scripts no servidor, especialmente aqueles que têm muita computação numérica sem usar muitas chamadas pesadas da biblioteca Luau ou da API do Roblox.

Ativando Nativo

Para habilitar a geração de código nativo para um Script , adicione o --!native comentário na parte superior: 1


--!nativo
print("Hello from native code!")

Não são necessárias alterações adicionais; o comportamento dos scripts de ejecución nativa é exatamente o mesmo de antes e apenas o desempenho é diferente. Todas as características da linguagem Luau e todas as APIs do Roblox permanecem suportadas.

1 No futuro, alguns scripts podem começar a ser rodados automaticamente se for determinado que sejam lucrativos, mas comentários colocados manualmente --!native são atualmente necessários.

Melhores Práticas

As seguintes dicas ajudarão você a se beneficiar mais da geração de código nativo:

  • É melhor habilitar essa função dentro de scripts que realizam muita computação diretamente dentro do Luau. Se você tiver muitas operações matemáticas em tabelas e especialmente buffer tipos, o script pode ser um bom candidato.

  • Apenas as funções do script são compiladas nativamente. O código no escopo exterior superior é muitas vezes ejecutado apenas uma vez e não beneficia tanto quanto as funções que são chamadas muitas vezes, especialmente aquelas que são chamadas a cada quadro.

  • Recomenda-se que você meça o tempo que um script ou uma operação leva com e sem o --!native comentário para julgar quando é melhor usá-lo. A ferramenta Script Profiler pode medir o desempenho dos scripts para tomar decisões informadas.

  • Pode ser tentador colocar o --!native comentário em cada script apenas no caso de alguns deles serem ejecutados mais rápido, mas a geração de código nativo tem algumas desvantagens:

    • O tempo de compilação de código é necessário, o que pode aumentar o tempo de inicialização dos servidores.
    • Memória extra é usada para armazenar código compilado nativamente.
    • Há um limite para a quantidade total permitida de código compilado nativamente em uma experiência.

Código para Evitar

Embora todas as funcionalidades se comportem da mesma forma com ou sem a geração de código nativa ativada, algumas delas não funcionarão nativamente e podem causar desoptimização ou uma reversão para a implementação interpretada. Entre elas estão:

  • Uso de chamadas obsoletas getfenv() / setfenv().
  • Uso de várias funções embutidas do Luau como math.asin() com argumentos não numéricos.
  • Passando parâmetros incorretamente digitados para funções digitadas, por exemplo, chamando foo(true) quando foo é declarado como function foo(arg: string). Lembre-se de sempre usar as anotações de tipo corretas.

Ao usar o Script Profiler, você pode comparar o tempo gasto por uma versão regular da função com a que foi criada de forma nativa. Se uma função marcada com --!native não estiver rodando de forma nativa, um ou mais fatores da lista acima podem estar desencadeando a des-otimização.

Usando Anotações de Tipo

A geração de código nativa tenta inferir o tipo mais provável para uma determinada variável, a fim de otimizar os caminhos do código. Por exemplo, assume-se que a + b é realizado em números ou que uma tabela é acessada em t.X . Dado que o operador está sobrecarregando, no entanto, a e b podem ser tabelas ou Vector3 tipos, ou t pode ser um tipo de dados do Roblox.

Embora a geração de código nativo suporte qualquer digitar, previsões erradas podem desencadear verificações desnecessárias, resultando em uma implementação de código mais lenta.

Para resolver alguns problemas comuns, anotações de tipo Luau em argumentos de função são verificadas, mas é especialmente recomendado anotar Vector3 argumentos:


--!nativo
-- "v" é assumido como uma tabela; a função tem um desempenho mais lento devido a verificações de tabela
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- "v" é declarado como um Vector3; código especializado para vetores é gerado
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

Ferramentas de Studio

As seguintes ferramentas do Studio são suportadas para scripts com --!native .

Depurando

Geral depuração de scripts é suportado, mas as visualizações para locais/upvalues podem ser incompletas e faltam variáveis de chamada stack quadros que estão sendo realizados nativamente.

Observe também que ao depurar um script com --!native, colocar pontos de interrupção desativará a execração nativa para essas funções.

Perfilador de Script

No Script Profiler, funções rodando nativamente são exibidas <native> ao lado delas:

Example of native functions flagged in the Script Profiler

Se o script estiver usando --!native, mas uma função não mostrar a <native> anotação, essa função pode não estar sendo ejecutada nativamente devido ao posicionamento de ponto de interrupção, ao uso de código desencorajado ou anotações de tipo incompatíveis.

Pilha de Luau

No Luau Heap profiler, a memória capturada por funções nativas é exibida como [native] elementos no gráfico.

Example of native memory usage flagged in the Luau Heap profiler

Análise de Tamanho

Todo script compilado nativamente consome memória. Quando o tamanho do código compilado atinge um limite predefinido, a compilação nativa pára e o código restante é rodado não nativamente. Isso torna essencial escolher scripts com cuidado para a compilação nativa.

Para monitorar o tamanho do código nativo de funções e scripts individuais:

  1. Certifique-se de que você está na exibição Server através do botão client/server toggle.
  2. Invoca debug.dumpcodesize() a partir da barra de comandos .

Na janela Output, você verá o número total de scripts e funções que foram nativamente compilados até o ponto de invocação, a memória consumida por seu código nativo e o limite de tamanho de código nativo. Seguindo o resumo, você verá uma tabela para cada script nativamente compilado em ordem decrescente de tamanho de código.

Example of native code size displayed in the Output window.

Para cada script, a saída exibe o número de funções compiladas e o consumo de memória de código nativo. Cada função é então listada em ordem decrescente do tamanho do código nativo, com funções anônimas mostradas como [anonymous] e scripts inteiros mostrados como [top level]. Na coluna final, a porcentagem é calculada em relação ao limite de tamanho de código nativo. Observe que o tamanho de código nativo das funções é relatado com precisão, mas o consumo de memória para scripts é arredondado até o tamanho de página mais próximo.

Limites e Solução de Problemas

Compilar código em instruções para uma CPU específica requer memória de armazenamento adicional. Além disso, as otimizações para funções complexas podem levar muito tempo para serem feitas. Atingir um limite interno reportará um erro na janela Output do Studio, incluindo:

A função 'f' na linha 20 excedeu o limite de instrução de bloco de código único

Este erro significa que um único bloco de código dentro de uma função usou mais de 64 mil instruções. Isso pode ser evitado simplificando a função ou dividindo-a em funções menores individuais.

A função 'f' na linha 20 excedeu o limite de blocos de código de função

Este erro significa que uma única função contém mais de 32 mil blocos internos de código. Blocos internos de código não se relacionam exatamente com os blocos de fluxo de controle em seu script, mas esse erro pode ser evitado simplificando o fluxo de controle na função ou dividindo-o em funções menores individuais.

A função 'f' na linha 200 excedeu o limite total de instruções do módulo

Este erro significa que, no total, a função atingiu o limite de 1 milhão de instruções para todo o script. Em alguns casos, a função relatada pode ter muitas instruções ou o limite pode ter sido atingido por funções anteriores no script. Para evitar esse problema, é recomendado mover funções especialmente grandes para um script não nativo separado. Você também pode tentar marcar esse script separado com --!native , mas 1 milhão de instruções consome muita memória e você pode exceder o limite de memória.

*A função 'f' na linha 20 encontrou uma falha de redução interna *(ou)
Erro interno: Falha na geração de código nativo (redução de montagem)

Às vezes, uma função contém bits complexos de código que o compilador de código nativo não pode Manipulador / alçaatualmente. Para evitar esse erro, inspecione expressões complexas no código e divida-as ou simplifique-as, mas também considere abrir um relatório de erro com um exemplo do código que falhou por esse motivo.

Limite de alocação de memória atingido para geração de código nativo

Este erro significa que o limite geral de memória para dados de código nativo foi atingido. Para evitar isso, tente remover --!native dos scripts mais intensivos em memória, permitindo que mais scripts menores fiquem abaixo do limite. Alternativamente, mova funções grandes ou raramente chamadas para um módulo não nativo separado.