← Alle Beitrage

Metal 4 Grundlagen: Was die neue Core-API tatsächlich verändert

Metal 4 ist kein Rewrite. Apple hat es als parallele API-Oberfläche neben den ursprünglichen Metal-Typen ausgeliefert, mit dem Präfix MTL4 für die neuen Typen, sodass eine App die neue Core-API inkrementell übernehmen kann, ohne bestehenden Render-Code neu schreiben zu müssen.1 Die Einordnung ist wichtig: Das Metal-Framework selbst gibt es schon lange; was sich auf der WWDC25 geändert hat, ist die Metal 4 Core-API.

Drei Dinge, die die neue Core-API für App-Entwickler tatsächlich verändert:

  1. Multi-Threaded Command Buffer Encoding wird zu einem erstklassigen Muster.
  2. Der Compute-Encoder absorbiert Blit- und Acceleration-Structure-Encoder zu einer einheitlichen Oberfläche.
  3. Maschinelles Lernen läuft als erstklassiger Pass-Typ neben Render- und Compute-Pässen und führt Core ML-Modelle auf der GPU-Timeline aus, ohne den Umweg über die CPU.

Die folgenden Abschnitte zeigen, wie jede dieser drei Änderungen in der Praxis aussieht, welche neuen Typen Entwickler dafür verwenden und welche Gründe Apples Dokumentation für die gewählte Form nennt.

TL;DR

  • MTL4CommandQueue, MTL4CommandBuffer, MTL4RenderCommandEncoder, MTL4ComputeCommandEncoder, MTL4MachineLearningCommandEncoder sind die neuen Typen.1 Die ursprünglichen MTL-präfixierten Typen bleiben erhalten. Sie übernehmen inkrementell, indem Sie beide mischen.
  • Command Buffer beziehen ihren Arbeitsspeicher aus einem separaten MTL4CommandAllocator, was es mehreren Threads ermöglicht, parallel auf mehrere Buffer zu encodieren. Ein einziger commit:count:-Aufruf übergibt das Batch an die Queue.1
  • MTL4ComputeCommandEncoder ersetzt drei frühere Encoder: MTLBlitCommandEncoder, MTLComputeCommandEncoder und MTLAccelerationStructureCommandEncoder.1 Ein Encoder, drei Aufgaben.
  • MTL4MachineLearningCommandEncoder führt Core ML-Modelle innerhalb eines Metal-Command-Buffers aus.2 Das System wählt für jedes Modell GPU oder Apple Neural Engine aus. Tensoren tragen Eingaben und Ausgaben; derselbe Command Buffer mischt ML-Inferenz mit Render- und Compute-Arbeit.
  • Resource Binding wechselt zu Argument-Tabellen (MTL4ArgumentTable) anstelle von Per-Encoder-Bind-Methoden. Alle Ressourcen sind ungetracked; Sie synchronisieren mit expliziten Barriers.1

Warum eine parallele API-Oberfläche

Apples Begründung für die parallele Typenstruktur, wörtlich aus der Dokumentation: „Metal 4 introduces several types with the MTL4 prefix that are completely independent from the original MTL types they replace, such as MTL4CommandQueue versus MTLCommandQueue. Other types are common to all versions of Metal.”1

Die Laufzeitprüfung ist einfach: Die App erkennt, ob das System Metal 4 unterstützt, erstellt eine MTL4CommandQueue, falls ja, und greift sonst auf MTLCommandQueue zurück. Der Typ der Queue, den die App erstellt, bestimmt, welche Familie von Typen der restliche Rendering-Code verwendet.1

Die andere Hälfte des Designs ermöglicht das Zusammenspiel beider Familien. MTLEvent und MTLSharedEvent synchronisieren über MTLCommandQueue- und MTL4CommandQueue-Instanzen hinweg.1 Eine App, die eine umfangreiche Metal-1-Codebasis ausliefert, kann ein einzelnes Subsystem auf Metal 4 umstellen, ohne die Synchronisationsmuster zu brechen, von denen der Rest der App abhängt.

Damit ist eine Frage beantwortet, die App-Entwickler seit der WWDC25 stellen: Muss ich meinen Metal-Code neu schreiben? Nein. Die Form der API fördert eine inkrementelle Übernahme pro Subsystem.

Multi-Threaded Command Buffer Encoding

Die wichtigste Laufzeitverbesserung: Der Speicher des Command Buffers stammt aus einem begleitenden Typ, MTL4CommandAllocator, statt aus der Queue. Jeder Thread kann seine Arbeit in seinen eigenen Command Buffer mit seinem eigenen Allocator encodieren, und die Queue committet die Buffer als Batch.

Apples API-Form: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)

Zwei operative Änderungen gegenüber der ursprünglichen API:

Command Buffer sind wiederverwendbar. Aus Apples Dokumentation: „You can reuse and repurpose each command buffer indefinitely by starting over, encoding new commands, and committing it again, instead of allocating a new buffer.”1 Das frühere Metal verlangte für jeden Commit einen frischen, transienten Buffer.

Keine automatische Ressourcenhaltung. „Each MTL4CommandBuffer instance doesn’t create strong references to resources.”1 Das Verhalten ähnelt makeCommandBufferWithUnretainedReferences() aus der älteren API. Apps müssen Ressourcenlebenszeiten explizit verwalten, damit Ressourcen am Leben bleiben, bis die GPU die Arbeit abschließt.

Das Frame-Allocator-Muster, das Apple in seinem Beispielcode ausliefert, verwendet einen Allocator pro Frame in flight (das Beispiel nutzt drei) und rotiert durch sie, während Frames den Lebenszyklus encode → render → display durchlaufen.1 Ein Aufruf von reset() auf dem Allocator zu Beginn jedes Frames gibt seinen Speicher zur Wiederverwendung an den Pool zurück.

Der vereinheitlichte Compute-Encoder

MTL4ComputeCommandEncoder ist „a new type that combines the functionality of its three predecessors: MTLBlitCommandEncoder, MTLComputeCommandEncoder, MTLAccelerationStructureCommandEncoder.”1

Die frühere API verlangte von Apps, je nach Aufgabenform den Encoder-Typ zu wechseln: Blit für Ressourcenkopien und Texturtransfers, Compute für Kernel-Dispatches, Acceleration-Structure für das Szenenmanagement beim Raytracing. Metal 4 fasst diese drei zu einer Oberfläche zusammen. Eine App, die einen Frame encodiert, der eine Acceleration Structure aufbaut, einen Denoising-Kernel dispatcht und eine Textur in einen Präsentationsbuffer kopiert, kann nun alle drei Vorgänge über einen einzigen Encoder-Typ abwickeln.

Auch der Render-Encoder hat eine Verhaltensänderung erfahren. MTL4RenderCommandEncoder unterstützt das Encodieren eines Render-Passes über mehrere Command Buffer hinweg, indem die Arbeit am Ende eines Render-Encoders unterbrochen und nach dem Beginn des nächsten in der Sequenz fortgesetzt wird.1 Apples Begründung: „This technique conceptually replaces the MTLParallelRenderCommandEncoder protocol and simplifies encoding a render pass in parallel with multiple threads because each thread can have its own render encoder instead of tying all of them to a single render encoder.”1

Das Muster bleibt: Paralleles Encoding wird zur natürlichen Form, und die API verlangt nicht länger einen einzigen Koordinatortyp.

Argument-Tabellen ersetzen Per-Encoder-Resource-Bindings

Die ursprüngliche Metal-Encoder-API stellte Methoden wie setVertexBuffer(_:offset:index:) und setFragmentTexture(_:index:) an jedem Encoder bereit, mit separaten, encoderinternen Bindungstabellen pro Stage.1 Metal 4 ersetzt dieses Muster durch eine explizite MTL4ArgumentTable-Instanz.

Apples Begründung des Designgewinns: „Metal 4 encoders don’t require memory for storing the binding tables for every resource type, at every stage. Each table consumes only the memory it needs to store its resource bindings.”1

Der Ablauf: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])

Eine einzelne Argument-Tabelle kann mehreren Encodern dienen, einschließlich Encodern auf verschiedenen Command Buffern, solange die Ressourcen, die sie bindet, für alle passend sind. Apples Dokumentation merkt an: „The memory and runtime savings add up with each common resource your encoders share, and each time you assign the argument table to a new encoder.”1

Es gibt einen Tradeoff. Frühere Versionen von Metal unterstützten Hazard Tracking für Texturen und Heaps, die sich über MTLTextureDescriptor.hazardTrackingMode oder MTLHeapDescriptor.hazardTrackingMode einklinkten.1 In Metal 4 gilt: „the framework considers all resources untracked. You need to synchronize pipeline stages that can concurrently access a resource if any of the shaders in these pipelines modify it.”1 Apps fügen explizite Barriers hinzu, um eine Stage zu verzögern, bis eine vorherige Stage abgeschlossen ist. Das ist mehr Code als das frühere Opt-in-Tracking, dafür aber vorhersagbare Performance und geringerer Laufzeit-Overhead.

Maschinelles Lernen als erstklassiger Pass

MTL4MachineLearningCommandEncoder ist die architektonisch bedeutendste Ergänzung. Apples Einordnung:2

„Metal 4 introduces the ability to run CoreML models efficiently from within the Metal workflow. This is useful for apps that need to apply the output from a model in a Metal context, such as rendering a scene or running a compute dispatch.”

Zwei Dinge geschehen gleichzeitig. Erstens läuft ML-Inferenz auf der GPU-Timeline, im selben Command Buffer wie Render- und Compute-Arbeit. Die App macht zwischen Modell-Inferenz und dem Render-Pass, der die Ausgabe konsumiert, keinen Umweg über die CPU. Zweitens wählt das System die Inferenz-Engine: „The system automatically chooses an inference engine, such as a device’s GPU or Apple Neural Engine (ANE) for each machine learning model. The GPU can run additional, independent render or compute work with the GPU when the system chooses to run a model on the ANE.”2

Der Entwicklungsablauf:2

  1. Konvertieren Sie ein Core ML-Modell mit metal-package-builder, das in den mitgelieferten Tools von Xcode 26 enthalten ist, in ein Metal ML Package.
  2. Fügen Sie das Metal ML Package zum Xcode-Projekt hinzu. Xcode kompiliert es zur Build-Zeit zu einer Metal-Library.
  3. Zur Laufzeit erstellt die App aus dieser Library einen MTL4MachineLearningPipelineState.
  4. Der Encoder nimmt den Pipeline State, einen MTLHeap für Scratch-Speicher sowie MTLTensor-Instanzen für Eingaben und Ausgaben entgegen.

MTLTensor ist ein neuer Ressourcentyp für mehrdimensionale Datenarrays.2 Apples Dokumentation merkt an, dass der Typ mit gängigen ML-Gewichtstypen wie int8 und fp16 arbeitet. Tensoren tragen Eingaben in das Modell hinein und Ausgaben heraus; für transiente Daten zwischen Inferenzaufrufen ergänzt Metal Shading Language Tensor-Typen, die direkt auf der GPU leben:2

  • tensor_handle: ein Handle auf einen MTLTensor, der auf der CPU erstellt wurde
  • tensor_inline: ein Tensor, der auf der GPU als Sicht auf einen Tensor oder Buffer definiert wird
  • cooperative_tensor: ein Tensor, der seine Elemente unter den Threads verteilt, die mit ihm arbeiten

Der Typ cooperative_tensor ist der latenzkritische Fall: „Cooperative tensors provide temporary memory for transient tensors by equally distributing their data among the threads that work with that tensor. This memory distribution reduces memory bandwidth by allocating the memory from thread-private or threadgroup-private address spaces, which is important for latency-critical, machine learning algorithms.”2

MSL hat zudem Tensor-Operatoren erhalten, die direkt im Shader-Code funktionieren: Konvolution, Matrixmultiplikation, Reduktion.2 Apps, die Gewichte zwischen Inferenz-Pässen manipulieren müssen, können das tun, ohne Tensoren zurück in den CPU-Speicher zu kopieren oder einen separaten Compute-Pass auszuführen; die Operatoren fügen sich in normale MSL-Kernel ein.

Eine Grenze ist erwähnenswert: „Machine learning encoders run Core ML models but they can’t build new networks or modify layers and inputs of existing ones; for those tasks, see Core ML and Metal Performance Shaders Graph.”2 Der ML-Encoder von Metal 4 ist für ausgelieferte Inferenz gedacht, nicht für Training oder Modellkonstruktion.

Was Metal 4 für den Apple-Stack bedeutet

Drei Erkenntnisse für App-Entwickler, die eine Metal-4-Übernahme planen:

  1. Inkrementell übernehmen, pro Subsystem. Die parallelen MTL4-präfixierten Typen und das eventbasierte Zusammenspiel mit der ursprünglichen API sind für eine partielle Migration ausgelegt. Wählen Sie ein Subsystem mit klarem Performance-Druck (einen Render-Pfad, eine Compute-Pipeline, eine Modell-Inferenzschleife) und migrieren Sie es zuerst.1
  2. Multi-Threaded Encoding ist die neue Normalität. Das Allocator-pro-Thread-Muster, die commit:count:-Batch-Übergabe und der Suspend/Resume-Mechanismus für Render-Pässe gehen alle davon aus, dass paralleles Encoding die Form ist, die performante Apps verwenden werden. Single-Thread-Encoding funktioniert nach wie vor, aber die Laufzeitgewinne des Frameworks summieren sich erst mit Multi-Thread-Adoption.1
  3. ML läuft im selben Command Buffer wie alles andere. Für Apps, die On-Device-Modell-Inferenz mit Rendering oder Compute kombinieren (Bildverarbeitungspipelines, die durch ein Core ML-Modell filtern, Echtzeit-Effekte, die von Klassifikatorausgaben abhängen, AR-Erlebnisse, deren Rendering von einem Inferenzergebnis pro Frame abhängt), ist die Möglichkeit, ML-Inferenz in denselben Command Buffer zu encodieren wie den Render-Pass, der sie konsumiert, der qualitative Wandel.2

Die Ergänzungen der Metal Shading Language verdienen eine eigene Behandlung. Tensor-Typen und -Operatoren im Shader-Code sowie Operationsdeskriptoren für benutzerdefinierte Operationen verändern, was ein Metal-Kernel ausdrücken kann. Das ist ein eigener Beitrag.

Der vollständige Apple-Ecosystem-Cluster: das Foundation Models On-Device LLM für das Framework, das auf diesem Stack aufsetzt; der Lebenszyklus benutzerdefinierter Adapter für entwicklergesteuerte Spezialisierung; Core ML On-Device-Inferenz für das ML-Framework, dessen Modelle Metal 4 nun inline ausführt. Der Hub befindet sich in der Apple Ecosystem Series.

FAQ

Ist Metal 4 ein eigenständiges Framework neben Metal?

Nein. Das Framework heißt nach wie vor Metal. Apples Dokumentation beschreibt Metal 4 als „the Metal 4 core API”: eine Reihe neuer Typen mit dem Präfix MTL4, die im selben Framework neben den ursprünglichen MTL-Typen ausgeliefert werden.1 Apps übernehmen die neuen Typen inkrementell, indem sie zur Laufzeit die Metal-4-Unterstützung erkennen und den passenden Queue-Typ erstellen.

Brauche ich iOS 26, um Metal 4 zu nutzen?

Das Metal-Framework unterstützt iOS 8+, aber die Metal 4 Core-API ist die Version, die Apple auf der WWDC25 eingeführt hat. Führen Sie eine Laufzeiterkennung aus und erstellen Sie je nach Geräteunterstützung entweder eine MTL4CommandQueue oder eine MTLCommandQueue.1

Wie verhält sich Metal 4 mit ML-Pässen zu Foundation Models?

Sie laufen auf unterschiedlichen Stacks. MTL4MachineLearningCommandEncoder führt Core ML-Modelle aus, die in Metal ML Packages konvertiert wurden, im selben Command Buffer wie Render- und Compute-Arbeit.2 Foundation Models ist ein separates Framework, das Apples On-Device-System-Sprachmodell mit eigener Session-API ausführt und im Foundation Models On-Device LLM-Beitrag behandelt wird. Beide ergänzen sich: Eine App kann Foundation Models für die Texterzeugung und Metal-4-ML-Pässe für Vision- oder Audio-Modell-Inferenz innerhalb ihrer Render-Schleife einsetzen.

Warum ist der Compute-Encoder jetzt vereinheitlicht?

Apples Dokumentation kombiniert MTLBlitCommandEncoder, MTLComputeCommandEncoder und MTLAccelerationStructureCommandEncoder zu MTL4ComputeCommandEncoder.1 Die Begründung ist eher operativ als rein performancegetrieben: Ein einziger Encoder-Typ für Compute-, Blit- und Acceleration-Structure-Arbeit vereinfacht das Pipeline-Management und reduziert das Encoder-Churn in Apps, die diese drei verschachteln.

Sind Store-Action-Optionen in Metal 4 noch verfügbar?

Nicht für MTL4RenderCommandEncoder. Apples Dokumentation merkt an: „Store-action options (see MTLStoreActionOptions) aren’t available because they don’t apply to Apple silicon GPUs.”1 Die Architekturentscheidung spiegelt Apples GPU-only-Zielsetzung für die Metal 4 Core-API wider.

Muss ich Argument-Tabellen verwenden?

In Metal 4: ja. Die Encoder-Protokolle stellen keine Bind-Methoden pro Ressource bereit. Sie konfigurieren Ressourcenbindungen auf einer MTL4ArgumentTable und weisen diese Tabelle einer oder mehreren Encoder-Stages zu.1 Der Laufzeitgewinn besteht darin, dass die Tabelle nur Speicher für die Bindungen reserviert, die sie tatsächlich nutzt, statt fester Per-Stage-Tabellen auf jedem Encoder.

Quellen


  1. Apple Developer, „Understanding the Metal 4 core API”. Vergleich der Typhierarchien (MTL4 vs. MTL), Verhalten von Command Queue und Buffer, Command-Allocator-Muster, Encoder-Vereinheitlichung, Argument-Tabellen, Hazard Tracking, Suspend/Resume-Render-Pässe. Abgerufen am 2026-05-04. 

  2. Apple Developer, „Machine learning passes”. MTL4MachineLearningCommandEncoder, MTLTensor, MSL-Tensor-Typen (tensor_handle, tensor_inline, cooperative_tensor), metal-package-builder, Auswahl der System-Inferenz-Engine (GPU/ANE), MSL-Tensor-Operatoren. Abgerufen am 2026-05-04. 

Verwandte Beiträge

SwiftData's Real Cost Is Schema Discipline

SwiftData's API is two macros. The cost is what happens after you ship. Optional fields are the cheap migration; non-opt…

15 Min. Lesezeit

Foundation Models Use Cases: General vs Content Tagging

iOS 26 Foundation Models has .general and .contentTagging use cases. Use Apple's rules to decide when prompting beats sp…

9 Min. Lesezeit

Building AI Systems: From RAG to Agents

I built a 3,500-line agent system with 86 hooks and consensus validation. Here's what I learned about RAG, fine-tuning, …

13 Min. Lesezeit