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 tu experiencia se pueden compilar directamente en las instrucciones de código de máquina que los procesadores ejecutan, en lugar de los códigos de bytes que operan en el núcleo de Luau. Esta característica se puede usar para mejorar la velocidad de ejecución para algunos scripts en el servidor, en particular aquellos que tienen mucho cálculo numérico sin usar demasiado el código de biblioteca de Luau o las llamadas de API

Habilitando nativo

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


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

Esto permite la generación de código nativo para todas las funciones en el script, y el alcance de nivel superior, si se considera rentable. No se requieren cambios adicionales; el comportamiento de los scripts que se ejecutan nativamente es exactamente el mismo que antes y solo la rendimiento es diferente. Todas las características del lenguaje Luau y todas las API de Roblox se mantienen admitidas.

Alternativamente, puede habilitar la generación de código nativo para una función individual agregando el atributo @native :


@native
local function f(x)
return (x + 1)
end
1 En el futuro, algunos scripts podrían comenzar a ejecutarse automáticamente si se determinó que era rentable, pero se requieren manualmente los comentarios de --!native .

Mejores Prácticas

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

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

  • Solo se compilan las funciones del script nativamente. El código en el alcance exterior superior a menudo se ejecuta solo una vez y no beneficia tanto como las funciones que se llaman muchas veces, especialmente las que se llaman cada marco.

  • Se recomienda que mida el tiempo que tarda un script o función con y sin compilación nativa para juzgar cuándo es mejor usarlo. La herramienta Script Profiler puede medir el rendimiento de las funciones para tomar decisiones informadas.

  • Puede ser tentador colocar el comentario de --!native en cada script sólo para asegurarse de que algunos de ellos se ejecutan más rápido, pero la generación de código nativo tiene algunas desventajas:

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

Estos problemas se pueden abordar con un uso adecuado de la atributo @native .

Código para evitar

Aunque todas las características se comportarán de la misma manera con o sin la generación de código nativo habilitada, algunas de ellas no se ejecutarán de forma nativa y podrían causar una degradación o un fallo de ejecución. Estas incluyen:

  • El uso de getfenv() / setfenv() llamadas.
  • Uso de varias funciones de Luau como math.asin() con argumentos no numéricos.
  • Pasar parámetros no válidos a funciones tipificadas, por ejemplo, al llamar foo cuando function foo(arg: string) se declara como 1> function foo(arg: cadena)1> . Recuerda siempre usar las anotaciones de tipo correctas 4> type annotations4> .

Al usar el Perfilador de Scripts, puede comparar el tiempo tomado por una versión regular de la función contra la que se compila nativamente. Si una función dentro de un script o marcado con --!native no aparece para ser ejecutada nativamente, uno o más factores de la lista de arriba pueden estar desencadenando la deoptimización.

Usando anotaciones de tipo

La generación de código nativo intenta inferir el tipo más probable para una variable específica para optimizar las rutas de código. Por ejemplo, se supone que a + b se realiza en números, o que se accede a una tabla

Aunque la generación de código nativo admita cualquier introducir, las predicciones pueden desencadenar controles innecesarios que resultan en la ejecución de código más lenta.

Para solucionar algunos problemas comunes, Luau tipo anotaciones en los argumentos de función se verifican, pero es especialmente recomendado anotar Vector3 argumentos:


--! nativo
-- '' v '' es asumido que es una tabla; la función funciona 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 ser un Vector3; el código especializado para los vectores se genera
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

Tutorial de Studio

La siguiente herramienta de Studio está soportada para --!native scripts y @native funciones.

Debug

Se soporta generalmente el debug de scripts, pero las vistas para usuarios/valores deben estar incompletas y faltar variables de ejecutar en el marco de llamada que están ejecutando nativamente.

Tenga en cuenta también que al debugger el código seleccionado para la compilación nativa, colocar puntos de interrupción desactivará la ejecución nativa para esas funciones.

Perfilador de Script

En el Script Profiler, las funciones que se ejecutan nativamente muestran <native> junto con ellas:

Example of native functions flagged in the Script Profiler

Si una función marcada como @native o dentro de un --!native > script no muestra la anotación de <native> , que función puede no estar ejecutando nativamente debido a un lugar de colocación de 2> código desalentado2> o a un mal equilibrio de tipo de anotación.

Pila de Luau

En el Luau Heap profiler, memory taken by native functions 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 nativamente compilado consume memoria. Cuando el tamaño del código recopilado alcanza un límite predeterminado, la compilación nativa termina y el código restante se ejecuta sin nativamente. Esto hace que sea esencial elegir scripts con cuidado para la compilación nativa.

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

  1. Asegúrese de que esté en Servidor vista a través de la botón de alternancia cliente/servidor .
  2. Invoca debug.dumpcodesize() desde la Barra de Comandos .

En la Salida ventana, verás el número total de scripts y funciones que se han compilado nativamente hasta el punto de invocación, el memoria consumida por su código nativo y el límite de tamaño del código nativo. Después de la resumen, verás una tabla para cada script que se ha compilado nativamente en orden descendente de tamaño del 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. Cada función se muestra entonces en orden descendente del tamaño del código nativo, con funciones anónimas mostradas como [anonymous] y el consumo de scripts como [top level] . En la columna final, se calcula el porcentaje con respecto al t

Límites y soluciones de problemas

Comilar código en instrucciones para un determinado CPU requiere memoria de almacenamiento adicional. Además, las optimizaciones para funciones complejas pueden tomar demasiado tiempo para ejecutarse. Alcanzar un límite interno reportará un error en la ventana de salida de Studio, incluida:

La función 'f' en la línea 20 superó el límite de instrucciones de un solo código bloqueado

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

La función 'f' en la línea 20 superó el límite 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 traducen exactamente a los bloques de control en tu script, pero este error se puede evitar simplificando el flujo de control en la función o dividiéndolo en bloques más pequeños.

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

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 haberse alcanzado por funciones anteriores en el script. Para evitar este problema, se recom

*Función 'f' en la línea 20 encontró un error de bajada interna *(o) Error interno: la generación de código nativo falló (ajuste de armado)

A veces una función contiene códigos complejos de código que el compilador de código nativo no puede controladoractualmente. Para evitar este error, inspecciona expresiones complejas en el código y divídelas o simplifícalas, pero también considera abrir un informe de error con un ejemplo del código que falló por este motivo.

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

Este error significa que el límite de memoria general para los datos del código nativo se ha alcanzado. Para evitar esto, intenta eliminar --!native > de los scripts más intensivos en memoria, permitiendo que más pequeños scripts encajen debajo del límite. Alternativamente, mueve grandes o infrecuentemente llamadas funciones a un módulo no nativo separado.