ネイティブコード生成

*このコンテンツは、ベータ版のAI(人工知能)を使用して翻訳されており、エラーが含まれている可能性があります。このページを英語で表示するには、 こちら をクリックしてください。

ネイティブコード生成に Luau のサポートがあるため、Luau VM が実行している通常のバイトコードではなく、CPU が実行するマシンコード指示に直接スクリプトがコンパイルできます。この機能は、サーバー上の特定のスクリプトの実行速度を向上させるために使用でき、特に多くの重い Luau ライブラリまたは Roblox API 呼び出しを使用しない数学計算を持つスクリプトを改善します。

ネイティブコード生成を有効にする

To enable native code generation for a , add the コメント at the top:¹


--!ネイティブ
print("Hello from native code!")

これにより、スクリプトのすべての機能とトップレベルのスコープに対するネイティブコード生成が有益であると判断された場合があります。追加の変更は必要ありません; ネイティブで実行されるスクリプトの動作は、以前と同じであり、パフォーマンスのみが異なります。Luau 言語のすべての機能と、すべての Roblox API がサポートされ続けます。

代わりに、@native 属性を追加して個々の機能のネイティブコード生成を有効にすることもできます:


@native
local function f(x)
return (x + 1)
end
1 将来、一部のスクリプトは、収益性が確保されると自動的にネイティブで実行を開始する可能性がありますが、手動で --!native コメントを配置する必要があります。

最良の実践

次のヒントは、ネイティブコード生成から最大限に利益を得るのに役立ちます:

  • Luau 内で多くの計算を直接行うスクリプト内でこの機能を有効にするのが最善です。テーブルや特に buffer タイプに多くの数学操作がある場合、スクリプトは良い候補になる可能性があります。

  • スクリプトの 機能 だけがネイティブでコンパイルされます。トップ外部の スコープ のコードは、多くの回呼ばれる機能と同じくらい実行されることは少なく、特にすべてのフレームで呼ばれる機能は、より多くの利点がありません。

  • スクリプトまたは関数がネイティブコンパイルでどのくらいの時間がかかるかを測定し、使用するタイミングを判断するために、ネイティブコンパイルなしで測定することをお勧めします。スクリプトプロファイラ ツールは、情報に基づいた意思決定を行うために、機能のパフォーマンスを測定できます。

  • すべてのスクリプトに コメントを配置することは誘惑的かもしれませんが、ネイティブコード生成にはいくつかの欠点があります:

    • コードのコンパイル時間が必要で、これはサーバーの起動時間を増加させる可能性があります。
    • 追加のメモリは、ネイティブにコンパイルされたコードを保存するために使用されます。
    • エクスペリエンス内のネイティブにコンパイルされたコードの合計許可量に制限があります。

これらの問題は、@native 属性の賢明な使用により解決できます。

回避するコード

すべての機能がネイティブコード生成を有効にしても無効にしても同じ動作をするが、一部はネイティブで実行されず、最適化が低下したり、インタープリテーション実行にバックアップされたりする可能性がある。これには以下が含まれます:

スクリプトプロファイラ を使用すると、ファンクションのレギュラーバージョンとネイティブにコンパイルされたバージョンの時間を比較できます。 スクリプト内の関数、または スクリプトにマークされた がネイティブで実行されているように見えない場合、上記のリストから 1つまたは複数の要因が、 最適化を停止する可能性があります。

タイプアノテーションを使用

ネイティブコード生成は、コードパスを最適化するために、特定の変数の最も可能なタイプを推測しようとします。たとえば、a + b が数字で実行されるか、またはテーブルが t.X でアクセスされると想定されます。ただし、オペレーターのオーバーロードにより、a および b はテーブルまたは Vector3 型、または t は Roblox データタイプかもしれません。

ネイティブコード生成はどんなタイプでもサポートしますが、予測ミスが不必要なチェックをトリガーし、コードの実行が遅くなる可能性があります。

いくつかの共通の問題を解決するには、Luau タイプの関数引数のアノテーションがチェックされますが、特に Vector3 引数にアノテーションを付けることをお勧めします:


--!ネイティブ
-- 「v」はテーブルと推定され、機能はテーブルチェックにより遅く実行されます
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- 「v」はベクトル3であると宣言され、ベクトル用のコードが生成されます
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

スタジオツール링

次のスタジオツールは、--!native スクリプトと @native 機能に対応しています。

デバッグ

スクリプトの一般的な デバッグ はサポートされますが、ローカル/アップバリューのビューは不完全で、ネイティブで実行されている 呼び出しスタック フレームから欠落した変数があります。

また、ネイティブコンパイル用に選択されたコードをデバッグするとき、ブレークポイント を配置すると、それらの機能のネイティブ実行が無効になります。

スクリプトプロファイラ

スクリプトプロファイラ では、ネイティブで実行される機能が次の横に表示されます:<native>

Example of native functions flagged in the Script Profiler

機能が またはスクリプト内の の標識が を表示しない場合、その機能は、ブレークポイントの配置、 忌み嫌われたコードの使用 、または一致しない タイプのアノテーション のため、ネイティブで実行されない可能性があります。

Luau ヘップ

In the Luau ヘープ profiler, ネイティブ機能によって取得されたメモリは、グラフの [native] 要素として表示されます。

Example of native memory usage flagged in the Luau Heap profiler

サイズ分析

ネイティブにコンパイルされたすべてのスクリプトがメモリを消費します。コンパイルされたコードのサイズがプリ定義された制限に達すると、ネイティブコンパイルが停止し、残りのコードは非ネイティブで実行されます。これは、ネイティブコンパイルのためにスクリプトを慎重に選択することが必須です。

個々の機能とスクリプトのネイティブコードサイズを監視するには:

  1. Make sure you're in サーバー ビューを通じて クライアント/サーバー切り替え ボタンで確認してください。
  2. 呼び出す debug.dumpcodesize() から コマンドバー

出力 ウィンドウ では、呼び出しポイントまでネイティブにコンパイルされたスクリプトと機能の合計数、ネイティブコードによって消費されたメモリ、ネイティブコードサイズ制限を見ることができます。まとめ要の後、コードサイズが下降順で表示されるネイティブにコンパイルされたスクリプトの表を見ることになります。

Example of native code size displayed in the Output window.

各スクリプトについて、出力はコンパイルされた機能数とネイティブコードメモリ消費を表示します。それぞれの機能は、ネイティブコードサイズが下降順にリストされ、匿名機能は [anonymous] 、全体のスクリプトは [top level] と表示されます。最後の列では、パーセンテージはネイティブコードサイズ制限に対して計算されます。機能のネイティブコードサイズは正確に報告されますが、スクリプトのメモリ消費は最も近いページサイズに丸められます。

制限とトラブルシュート

特定の CPU 用のコードを指示に変換するには、追加のストレージメモリが必要です。さらに、複雑な機能の最適化は実行に時間がかかりすぎる可能性があります。内部制限に達すると、Studio の 出力 ウィンドウにエラーが報告され、以下を含みます:

ライン 20 の機能 'f' は、単一コードブロック命令制限を超えました

このエラーは、機能内の単一のコードブロックが 64K 以上の指示を使用したことを意味します。これは、機能を簡素化するか、個々の小さな機能に分割することで回避できます。

ライン 20 の機能 'f' は、機能コードブロック制限を超えました

このエラーは、単一の関数に 32K 以上のコード内ブロックが含まれていることを意味します。コードの内部ブロックは、スクリプトの制御フローブロックに完全にマップするわけではありませんが、このエラーは、機能内の制御フローを簡素化するか、個々の小さな機能に分割することで回避できます。

ライン 200 の機能 'f' は、モジュール指示の制限を超えました

このエラーは、合計で機能が全体のスクリプトの 100万インストラクションの制限に達したことを意味します。いくつかの場合、報告された機能自体には多くの指示があるか、制限はスクリプトの早期に機能によって達されている可能性があります。この問題を避けるために、特に大きな機能を別の非ネイティブスクリプトに移動するか、他の機能に @native を使用することをお勧めします。別のスクリプトを --!native でマークすることもできますが、100万の指示は多くのメモリを占有し、メモリ制限を超える可能性があります。

ライン 20 の機能 'f' は内部の低下失敗を発見しました (または) 内部エラー: ネイティブコード生成に失敗しました (アセンブリ低下)

時々、機能には、ネイティブコードコンパイラーが現在処理できない複雑なコードビットが含まれています。このエラーを避けるには、コードで複雑な式を調べて分離または簡素化し、またこの理由で失敗したコードの例を持つバグレポートを開くことも考えてください。

ネイティブコード生成のメモリ割り当て制限に達しました

このエラーは、ネイティブコードデータの全体メモリ制限に達したことを意味します。これを避けるには、よりメモリ使用量の多いスクリプトから --!native を削除し、より小さなスクリプトを制限の下に収めることができます。代わりに、大規模または頻繁に呼ばれない機能を別の非ネイティブモジュールに移動します。