Generación de código nativo

Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Con el soporte de Luau para la generación de código nativo, los scripts del lado del servidor en su experiencia se pueden compilar directamente en las instrucciones de código de la máquina que ejecutan las CPUs, en lugar del código de bytes regular en el que opera la VM de Luau. Esta característica se puede usar para mejorar la velocidad de ejecución de algunos scripts en el servidor, en particular los que tienen mucha computación numérica sin usar demasiadas llamadas pesadas a la biblioteca de Luau o a la API de Roblox.

Habilitar nativo

Para habilitar la generación de código nativo para un Script, agregue el --!native comentario en la parte superior: 1


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

No se requieren cambios adicionales; el comportamiento de los scripts de ejecución nativa es exactamente el mismo que antes y solo el rendimiento es diferente. Todas las características del lenguaje Luau y todas las API de Roblox siguen siendo compatibles.

1 En el futuro, algunos scripts podrían comenzar a ejecutarse automáticamente si se determina que son rentables, pero se requieren comentarios colocados manualmente --!native.

Mejores Prácticas

Los siguientes consejos te ayudarán a beneficiarte más de la generación de código nativo:

  • Lo mejor es habilitar esta función dentro de los scripts que realizan mucha computación directamente dentro de Luau. Si tiene muchas operaciones matemáticas en tablas y especialmente buffer tipos, el script puede ser un buen candidato.

  • Solo las funciones del script se compilan de forma nativa. El código en el ámbito exterior superior a menudo se ejecuta solo una vez y no se beneficia tanto como las funciones que se llaman muchas veces, especialmente las que se llaman cada fotograma.

  • Se recomienda que midas el tiempo que tarda un script o una operación con y sin el comentario --!native para juzgar cuándo es mejor usarlo. La herramienta Script Profiler puede medir el rendimiento de los scripts para tomar decisiones informadas.

  • Puede ser tentador colocar el comentario --!native en cada script por si acaso algunos de ellos se ejecutarán más rápido, pero la generación de código nativo tiene algunos inconvenientes:

    • Se requiere tiempo de compilación de código, lo que puede aumentar el tiempo de inicio de los servidores.
    • Se ocupa memoria extra para almacenar el código compilado de forma nativa.
    • Hay un límite en la cantidad total permitida de código compilado de forma nativa en una experiencia.

Código para evitar

Si bien todas las funciones se comportarán igual con o sin generación de código nativa habilitada, algunas de ellas no se ejecutarán de forma nativa y podrían causar una desoptimización o un retroceso a la ejecución interpretada. Estos incluyen:

  • Uso de llamadas obsoletas getfenv() / setfenv().
  • Uso de varias funciones incorporadas de Luau como math.asin() con argumentos no numéricos.
  • Pasando parámetros incorrectamente tipados a funciones tipadas, por ejemplo, llamando foo(true) cuando foo se declara como function foo(arg: string). Recuerde siempre usar las annotaciones de tipo correctas.

Al usar el Script Profiler, puede comparar el tiempo empleado por una versión regular de la función con la compilada de forma nativa. Si una función marcada con --!native no parece ejecutarse de forma nativa, uno o más de los factores de la lista anterior pueden estar desencadenando la desoptimización.

Usando Anotaciones de Tipo

La generación de código nativo intenta inferir el tipo más probable de una variable dada para optimizar las rutas de código. Por ejemplo, se asume que a + b se realiza en números o que se accede a una tabla en t.X . Dado que el sobrecarga del operador, sin embargo, a y b pueden ser tablas o Vector3 tipos, o t pueden ser un tipo de datos de Roblox.

Si bien la generación de código nativo admitirá cualquier introducir, las predicciones erróneas pueden desencadenar verificaciones innecesarias, lo que resultará en una ejecución de código más lenta.

Para resolver algunos problemas comunes, se comprueban las anotaciones de tipo Luau en los argumentos de la función, pero se recomienda especialmente anotar Vector3 argumentos:


--!nativo
-- se asume que "v" es una tabla; la función se comporta más lentamente debido a las comprobaciones de la tabla
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- "v" se declara como un Vector3; se genera código especializado para vectores
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

Herramientas de Studio

Las siguientes herramientas de Studio son compatibles con scripts con --!native .

Depurando

La depuración general de scripts es compatible, pero las vistas para locales/upvalues pueden estar incompletas y faltan variables de llamada de pila cuadros que se están ejecutando de forma nativa.

Tenga en cuenta que al depurar un script con --!native, colocar puntos de interrupción desactivará la ejecución nativa de esas funciones.

Perfilador de scripts

En el Script Profiler, las funciones que se ejecutan de forma nativa se muestran <native> junto a ellas:

Example of native functions flagged in the Script Profiler

Si el script está usando --!native pero una función no muestra la <native> anotación, es posible que esa función no se ejecute de forma nativa debido a la colocación de punto de rotura, el uso de desalentó el código o las anotaciones de tipo no coincidentes.

Montón de Luau

En el Luau Heap profiler, la memoria tomada por funciones nativas se muestra como [native] elementos en el gráfico.

Example of native memory usage flagged in the Luau Heap profiler

Análisis de Tamaño

Cada script compilado de forma nativa consume memoria. Cuando el tamaño del código compilado alcanza un límite predefinido, la compilación nativa se detiene y el código restante se ejecuta de forma no nativa. Esto hace que sea esencial elegir los scripts con cuidado para la compilación nativa.

Para monitorizar el tamaño del código nativo de funciones y scripts individuales:

  1. Asegúrese de que está en la vista Server a través del botón client/server toggle.
  2. Invoca debug.dumpcodesize() desde la barra de comandos .

En la ventana Output, verás el número total de scripts y funciones que se han compilado nativamente hasta el punto de invocación, el almacenamiento consumido por su código nativo y el límite de tamaño de código nativo. Siguiendo el resumen, verás una tabla para cada script compilado nativamente en orden descendente de tamaño de código.

Example of native code size displayed in the Output window.

Para cada script, la salida muestra el número de funciones compiladas y el consumo de memoria de código nativo. Luego, cada función se enumera en orden decreciente de tamaño de código nativo, con funciones anónimas mostradas como [anonymous] y scripts enteros mostrados como [top level]. En la columna final, se calcula el porcentaje con respecto al límite de tamaño de código nativo. Tenga en cuenta que el tamaño de código nativo de las funciones se informa con precisión, pero el consumo de memoria de los scripts se redondea al tamaño de página más próximo.

Límites y solución de problemas

La compilación de código en instrucciones para una CPU en particular requiere almacenamiento adicional. Además, las optimizaciones para funciones complejas pueden tardar demasiado tiempo en ejecutarse. Atacar un límite interno reportará un error en la ventana Output de Studio, que incluye:

La función 'f' en la línea 20 superó el límite de instrucciones de bloque de código único

Este error significa que un solo bloque de código dentro de una función usó más de 64K instrucciones. Esto se puede evitar simplificando la función o dividiéndola en funciones individuales más pequeñas.

La función 'f' en la línea 20 superó el límite de bloque de código de función

Este error significa que una sola función contiene más de 32K bloques internos de código. Los bloques internos de código no se asignan exactamente a los bloques de control-flow en su script, pero este error se puede evitar simplificando el control-flow en la función o dividiéndolo en funciones individuales más pequeñas.

La función 'f' en la línea 200 superó el límite de instrucciones del módulo total

Este error significa que, en total, la función ha alcanzado un límite de 1 millón de instrucciones para todo el script. En algunos casos, la función reportada puede tener muchas instrucciones, o el límite puede haber sido alcanzado por funciones anteriores en el script. Para evitar este problema, se recomienda mover funciones particularmente grandes a un script no nativo separado. También puede intentar marcar ese script separado con --!native , pero 1 millón de instrucciones ocupa mucho almacenamiento y puede exceder el límite de almacenamiento.

*La función 'f' en la línea 20 encontró un error interno de bajada *(o)
Error interno: falló la generación de código nativo (bajada de montaje)

A veces una función contiene bits complejos de código que el compilador de código nativo no puede controladoractualmente. Para evitar este error, inspeccione expresiones complejas en el código y divídelos o simplifícalos, pero también considere abrir un informe de errores con un ejemplo del código que falló por esta razón.

Límite de asignación de almacenamiento alcanzado para la generación de código nativo

Este error significa que se ha alcanzado el límite de almacenamiento general para los datos de código nativo. Para evitar esto, intente eliminar --!native de los scripts que requieren más almacenamiento, lo que permite que más scripts más pequeños se ajusten al límite. Alternativamente, mueva las funciones grandes o poco frecuentes a un módulo no nativo separado.