Metal 4の要点:新しいコアAPIが実際に変えるもの
Metal 4は書き直しではありません。Appleはこれを既存のMetal型と並行するAPI表面として提供し、新しい型にはMTL4プレフィックスを付けることで、アプリは既存のレンダリングコードを書き直すことなく、新しいコアAPIを段階的に採用できるようになっています。1 この位置づけが重要です。Metalフレームワーク自体は長く出荷されてきたものであり、WWDC25で変わったのはMetal 4のコアAPIなのです。
新しいコアAPIがアプリ開発者にとって実際に変える3つのこと。
- マルチスレッドのコマンドバッファエンコーディングが第一級のパターンとなります。
- computeエンコーダがblitおよびacceleration-structureエンコーダを吸収し、1つの統合された表面となります。
- 機械学習がレンダリングおよびcomputeと並ぶ第一級のパス型として実行され、CPUへのラウンドトリップなしにGPUタイムライン上でCore MLモデルを実行します。
以下のセクションでは、これら3つの変更が実際にどのような形で現れるか、開発者が手を伸ばす新しい型、そしてその形を採用した理由としてAppleのドキュメントが挙げているものを順に見ていきます。
TL;DR
MTL4CommandQueue、MTL4CommandBuffer、MTL4RenderCommandEncoder、MTL4ComputeCommandEncoder、MTL4MachineLearningCommandEncoderが新しい型です。1 既存のMTLプレフィックス型は残ります。両方を混在させることで段階的に採用できます。- コマンドバッファは作業メモリを別個の
MTL4CommandAllocatorから取得します。これにより、複数のスレッドが複数のバッファに並行してエンコードできるようになります。1回のcommit:count:呼び出しでバッチをキューに送信します。1 MTL4ComputeCommandEncoderは3つの旧エンコーダ、MTLBlitCommandEncoder、MTLComputeCommandEncoder、MTLAccelerationStructureCommandEncoderを置き換えます。1 1つのエンコーダで3つの仕事をこなします。MTL4MachineLearningCommandEncoderはMetalコマンドバッファ内でCore MLモデルを実行します。2 システムは各モデルに対してGPUまたはApple Neural Engineを選びます。テンソルが入力と出力を運び、同じコマンドバッファがML推論をレンダリングおよびcompute作業と混在させます。- リソースバインディングはエンコーダごとのバインドメソッドではなく、引数テーブル(
MTL4ArgumentTable)に移行します。すべてのリソースは追跡されず、明示的なバリアで同期します。1
なぜ並行するAPI表面なのか
並行する型を選んだ理由について、ドキュメントから一字一句引用します。「Metal 4では、置き換える既存のMTL型から完全に独立したMTL4プレフィックス付きの型をいくつか導入しています。例えばMTL4CommandQueueとMTLCommandQueueの関係です。それ以外の型は、すべてのバージョンのMetalで共通です。」1
ランタイムでのチェックはシンプルです。アプリはシステムがMetal 4をサポートするかどうかを検出し、サポートする場合はMTL4CommandQueueを作成し、そうでなければMTLCommandQueueにフォールバックします。アプリが作成するキューの型によって、レンダリングコードの残りが使用する型ファミリーが決まります。1
設計のもう半分は、2つのファミリーの相互運用を可能にしています。MTLEventとMTLSharedEventはMTLCommandQueueとMTL4CommandQueueの両方のインスタンス間で同期します。1 大規模なMetal 1コードベースを抱えるアプリは、アプリの残りの部分が依存している同期パターンを壊すことなく、単一のサブシステムをMetal 4に切り替えられるのです。
これでWWDC25以来アプリ開発者が問い続けてきた疑問への答えが出ます。Metalコードを書き直す必要があるのか?いいえ。APIの形状が、サブシステムごとの段階的な採用を促しています。
マルチスレッドのコマンドバッファエンコーディング
目玉となるランタイム改善は、コマンドバッファのメモリがキューからではなく、コンパニオン型であるMTL4CommandAllocatorから提供されるという点です。各スレッドが自身のアロケータを使って独自のコマンドバッファに作業をエンコードでき、キューはバッファをバッチとしてコミットします。
AppleのAPIの形状はこうです。1
let device: MTLDevice = ...
let commandQueue: MTL4CommandQueue = device.makeMTL4CommandQueue()
var commandAllocators: [MTL4CommandAllocator] = ...
let commandBuffer: MTL4CommandBuffer = device.makeCommandBuffer()
// Per frame:
let frameAllocator = commandAllocators[frameNumber % kMaxFramesInFlight]
frameAllocator.reset()
commandBuffer.beginCommandBuffer(allocator: frameAllocator)
// ...encode commands to commandBuffer...
commandBuffer.endCommandBuffer()
commandQueue.commit(commandBuffer, count: 1)
既存のAPIからの2つの運用上の変更点。
コマンドバッファは再利用可能です。 Appleのドキュメントによれば、「各コマンドバッファは、新しいバッファを割り当てる代わりに、最初からやり直し、新しいコマンドをエンコードし、再びコミットすることで、無期限に再利用および再利用転用できます。」1 以前のMetalでは、コミットごとに新しい一時的なバッファが必要でした。
自動的なリソース保持はありません。 「各MTL4CommandBufferインスタンスはリソースへの強参照を作成しません。」1 この挙動は古いAPIのmakeCommandBufferWithUnretainedReferences()に似ています。アプリはリソースのライフタイムを明示的に管理し、GPUが作業を完了するまでリソースが生きていることを保証する必要があります。
Appleがサンプルコードで提供しているフレームアロケータパターンは、フライト中の各フレームに対して1つのアロケータを使用し(サンプルでは3つを使用)、フレームがエンコード→レンダリング→表示のライフサイクルを進むにつれてそれらをローテーションします。1 各フレームの開始時にアロケータのreset()を呼ぶと、そのメモリがプールに返却され、再利用できるようになります。
統合されたcomputeエンコーダ
MTL4ComputeCommandEncoderは「3つの先行エンコーダ、MTLBlitCommandEncoder、MTLComputeCommandEncoder、MTLAccelerationStructureCommandEncoderの機能を組み合わせた新しい型」です。1
旧APIでは、作業の形状に応じてエンコーダ型を切り替える必要がありました。リソースのコピーやテクスチャ転送にはblit、カーネルディスパッチにはcompute、レイトレーシングのシーン管理にはacceleration-structureです。Metal 4はこれら3つを1つの表面に集約します。アクセラレーション構造を構築し、デノイズカーネルをディスパッチし、テクスチャをプレゼンテーションバッファにコピーするフレームをエンコードするアプリは、今や1つのエンコーダ型でこれら3つすべてを実行できるようになります。
レンダーエンコーダにも挙動の変更が加わりました。MTL4RenderCommandEncoderは、1つのレンダーエンコーダの末尾で作業を中断し、シーケンス内の次のレンダーエンコーダの先頭でそれを再開することで、コマンドバッファをまたいだレンダーパスのエンコーディングをサポートします。1 Appleの位置づけはこうです。「この技術は概念的にMTLParallelRenderCommandEncoderプロトコルを置き換え、複数のスレッドで並行してレンダーパスをエンコードすることを簡素化します。各スレッドが独自のレンダーエンコーダを持てるため、すべてのスレッドを単一のレンダーエンコーダに結びつける必要がないからです。」1
パターンは一貫しています。並行エンコーディングが自然な形となり、APIは単一のコーディネータ型を必要としなくなります。
引数テーブルがエンコーダごとのリソースバインディングを置き換える
旧MetalエンコーダAPIは、各エンコーダにsetVertexBuffer(_:offset:index:)やsetFragmentTexture(_:index:)などのメソッドを公開し、エンコーダ内部にステージごとに分離されたバインディングテーブルを持っていました。1 Metal 4はそのパターンを明示的なMTL4ArgumentTableインスタンスに置き換えます。
設計上の利点についてのAppleの位置づけはこうです。「Metal 4のエンコーダは、すべてのリソース型のバインディングテーブルを各ステージで保存するためのメモリを必要としません。各テーブルは、リソースバインディングを保存するために必要なメモリのみを消費します。」1
フローはこうです。1
let descriptor = MTL4ArgumentTableDescriptor()
descriptor.maxBufferBindCount = ...
descriptor.maxTextureBindCount = ...
let argumentTable = device.makeArgumentTable(descriptor: descriptor)
argumentTable.setResource(buffer, bufferIndex: 0)
argumentTable.setSamplerState(sampler, index: 0)
renderEncoder.setArgumentTable(argumentTable, stages: [.vertex, .fragment])
1つの引数テーブルは、バインドするリソースがすべてに対して適切である限り、異なるコマンドバッファ上のエンコーダを含む複数のエンコーダに対して機能します。Appleのドキュメントは次のように記しています。「メモリとランタイムの節約は、エンコーダが共有するリソースが共通であるたびに、また引数テーブルを新しいエンコーダに割り当てるたびに積み重なります。」1
トレードオフがあります。旧バージョンのMetalは、MTLTextureDescriptor.hazardTrackingModeまたはMTLHeapDescriptor.hazardTrackingModeを介してオプトインしたテクスチャとヒープに対するハザード追跡をサポートしていました。1 Metal 4では、「フレームワークはすべてのリソースを追跡されないものとみなします。これらのパイプライン内のシェーダのいずれかがリソースを変更する場合、リソースに同時にアクセスできるパイプラインステージを同期する必要があります。」1 アプリは、前のステージが終わるまであるステージを遅延させるために明示的なバリアを追加します。これは旧来のオプトイン追跡よりもコードが多いですが、その代わりに予測可能なパフォーマンスとより低いランタイムオーバーヘッドが得られます。
第一級のパスとしての機械学習
MTL4MachineLearningCommandEncoderはアーキテクチャ的に最も重要な追加です。Appleの位置づけはこうです。2
「Metal 4は、Metalワークフロー内からCoreMLモデルを効率的に実行する機能を導入します。これは、シーンのレンダリングやcomputeディスパッチの実行のように、モデルからの出力をMetalコンテキストで適用する必要があるアプリにとって有用です。」
2つのことが同時に起こっています。第一に、ML推論はレンダリングやcompute作業と同じコマンドバッファ内で、GPUタイムライン上で実行されます。アプリはモデル推論と、その出力を消費するレンダーパスの間で、CPUへのラウンドトリップを行いません。第二に、システムが推論エンジンを選択します。「システムは、デバイスのGPUやApple Neural Engine(ANE)など、各機械学習モデルに対して推論エンジンを自動的に選択します。システムがモデルをANEで実行することを選んだ場合、GPUは追加の独立したレンダリングまたはcompute作業をGPUで実行できます。」2
開発ワークフロー。2
- Xcode 26のバンドルツールに含まれる
metal-package-builderを使って、Core MLモデルをMetal MLパッケージに変換します。 - Metal MLパッケージをXcodeプロジェクトに追加します。Xcodeはビルド時にそれをMetalライブラリにコンパイルします。
- ランタイムで、アプリはそのライブラリから
MTL4MachineLearningPipelineStateを作成します。 - エンコーダはパイプラインステート、スクラッチメモリ用の
MTLHeap、そして入力と出力のためのMTLTensorインスタンスを受け取ります。
MTLTensorは多次元データ配列のための新しいリソース型です。2 Appleのドキュメントは、この型がint8やfp16のような一般的なML重み型で動作することを記しています。テンソルは入力をモデルに運び、出力をモデルから持ち出します。推論呼び出し間の一時的なデータについては、Metal Shading LanguageがGPU上に直接存在するテンソル型を追加しています。2
tensor_handle:CPU上で作成されたMTLTensorへのハンドルtensor_inline:GPU上で定義されたテンソルまたはバッファへのビューとしてのテンソルcooperative_tensor:要素を扱うスレッド間で分散するテンソル
cooperative_tensor型はレイテンシに敏感なケース向けです。「協調テンソルは、そのテンソルを扱うスレッド間でデータを均等に分散することで、一時的なテンソルのための一時メモリを提供します。このメモリ分散は、スレッドプライベートまたはスレッドグループプライベートなアドレス空間からメモリを割り当てることで、メモリ帯域幅を削減します。これはレイテンシクリティカルな機械学習アルゴリズムにとって重要です。」2
MSLはまた、シェーダコードで直接動作するテンソル演算子を取り入れました。畳み込み、行列乗算、リダクションなどです。2 推論パスの間で重みを操作する必要があるアプリは、テンソルをCPUメモリに戻したり別個のcomputeパスを実行したりすることなく、それを行えます。演算子は通常のMSLカーネルに収まります。
引用に値する境界線が1つあります。「機械学習エンコーダはCore MLモデルを実行しますが、新しいネットワークを構築したり既存のレイヤーや入力を変更したりすることはできません。それらの作業については、Core MLとMetal Performance Shaders Graphをご覧ください。」2 Metal 4のMLエンコーダは、出荷用の推論のためのものであり、トレーニングやモデル構築のためのものではありません。
Metal 4がAppleスタックにとって意味するもの
Metal 4の採用を計画しているアプリ開発者にとっての3つの要点。
- 段階的に、サブシステム単位で採用しましょう。 並行する
MTL4プレフィックス型と既存のAPIとのイベントベースの相互運用は、部分的なマイグレーションのために設計されています。明確なパフォーマンス上の圧力がかかっているサブシステム(レンダリングパス、computeパイプライン、モデル推論ループ)を選んで、最初にマイグレーションしましょう。1 - マルチスレッドエンコーディングが新しい標準です。 スレッドごとのアロケータパターン、
commit:count:バッチ送信、サスペンド/レジュームのレンダーパス機構はすべて、パフォーマンスの高いアプリが使用する形として並行エンコーディングを前提としています。シングルスレッドエンコーディングも依然として動作しますが、フレームワークのランタイム上の利得はマルチスレッド採用とともに積み重なります。1 - MLは他のすべてと同じコマンドバッファ内で実行されます。 オンデバイスのモデル推論をレンダリングやcomputeと組み合わせるアプリ(Core MLモデルを通してフィルタリングする画像処理パイプライン、分類器の出力に依存するリアルタイムエフェクト、フレームごとの推論結果にレンダリングが依存するAR体験)にとって、ML推論をその出力を消費するレンダーパスと同じコマンドバッファにエンコードできることは質的な変化です。2
Metal Shading Languageへの追加は、独立した扱いに値します。シェーダコード内のテンソル型と演算子、加えてカスタム操作のための操作ディスクリプタは、Metalカーネルが表現できるものを変えます。それは別の記事で扱います。
Apple Ecosystemクラスタの全体像はこうです。このスタックの上で動作するフレームワークについてはFoundation ModelsオンデバイスLLM、開発者管理の専門化についてはカスタムアダプタのライフサイクル、Metal 4が今やインラインで実行するモデルのMLフレームワークについてはCore MLオンデバイス推論。ハブはApple Ecosystem Seriesにあります。
FAQ
Metal 4はMetalとは別のフレームワークですか?
いいえ。フレームワークは依然としてMetalです。Appleのドキュメントは、Metal 4を「Metal 4のコアAPI」と表現しています。同じフレームワーク内で既存のMTL型と並行して提供される、MTL4プレフィックス付きの新しい型のセットです。1 アプリはランタイムでMetal 4のサポートを検出し、適切なキュー型を作成することで、新しい型を段階的に採用します。
Metal 4を使うにはiOS 26が必要ですか?
MetalフレームワークはiOS 8以降をサポートしますが、Metal 4のコアAPIはAppleがWWDC25で導入したバージョンです。ランタイム検出を実行し、デバイスがサポートするものに基づいてMTL4CommandQueueまたはMTLCommandQueueのいずれかを作成しましょう。1
Metal 4のMLパスとFoundation Modelsの関係は?
これらは異なるスタック上で動作します。MTL4MachineLearningCommandEncoderは、Core MLモデルをMetal MLパッケージに変換したものを、レンダリングやcompute作業と同じコマンドバッファ内で実行します。2 Foundation Modelsは別個のフレームワークで、Appleのオンデバイスシステム言語モデルを独自のセッションAPIで実行します。これはFoundation ModelsオンデバイスLLMの記事で取り上げています。両者は補完的です。アプリはテキスト生成にFoundation Modelsを使い、レンダリングループ内の視覚や音声モデル推論にMetal 4のMLパスを使うことができます。
なぜcomputeエンコーダが今や統合されているのですか?
Appleのドキュメントは、MTLBlitCommandEncoder、MTLComputeCommandEncoder、MTLAccelerationStructureCommandEncoderをMTL4ComputeCommandEncoderに統合しています。1 その正当化はパフォーマンスのみではなく運用面のものです。compute、blit、acceleration-structure作業のための単一のエンコーダ型は、パイプライン管理を簡素化し、これら3つを交互に行うアプリでのエンコーダの入れ替わりを減らします。
Metal 4でストアアクションのオプションは依然として利用可能ですか?
MTL4RenderCommandEncoderでは利用できません。Appleのドキュメントは次のように記しています。「ストアアクションのオプション(MTLStoreActionOptionsを参照)は、Apple silicon GPUに適用されないため、利用できません。」1 このアーキテクチャ上の決定は、Metal 4のコアAPIに対するAppleのGPU限定のターゲットを反映しています。
引数テーブルを使う必要はありますか?
Metal 4ではそうです。エンコーダプロトコルはリソースごとのバインドメソッドを公開しません。MTL4ArgumentTableにリソースバインディングを設定し、そのテーブルを1つ以上のエンコーダステージに割り当てます。1 ランタイム上の利点は、テーブルが各エンコーダ上の固定サイズのステージごとのテーブルではなく、実際に使用するバインディングのためのメモリのみを割り当てることです。
References
-
Apple Developer, “Understanding the Metal 4 core API”. Type hierarchy comparison (
MTL4vsMTL), command queue and buffer behavior, command allocator pattern, encoder unification, argument tables, hazard tracking, suspend/resume render passes. Retrieved 2026-05-04. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, “Machine learning passes”.
MTL4MachineLearningCommandEncoder,MTLTensor, MSL tensor types (tensor_handle,tensor_inline,cooperative_tensor),metal-package-builder, system inference engine selection (GPU/ANE), MSL tensor operators. Retrieved 2026-05-04. ↩↩↩↩↩↩↩↩↩↩↩