← Wszystkie wpisy

Metal 4 — najważniejsze informacje: co tak naprawdę zmienia nowe rdzeniowe API

Metal 4 to nie przepisanie od zera. Apple udostępnił go jako równoległą warstwę API obok pierwotnych typów Metal, opatrując nowe prefiksem MTL4, dzięki czemu aplikacja może przyjmować nowe rdzeniowe API stopniowo, bez przepisywania istniejącego kodu renderującego.1 Sposób ujęcia ma znaczenie: sam framework Metal jest dostarczany od dawna; tym, co zmieniło się na WWDC25, jest rdzeniowe API Metal 4.

Trzy rzeczy, które nowe rdzeniowe API faktycznie zmienia dla deweloperów aplikacji:

  1. Wielowątkowe kodowanie buforów poleceń staje się pełnoprawnym wzorcem.
  2. Encoder obliczeniowy wchłania encodery blit oraz struktur akceleracji, tworząc jedną ujednoliconą warstwę.
  3. Uczenie maszynowe działa jako pełnoprawny typ przebiegu obok renderowania i obliczeń, wykonując modele Core ML na osi czasu GPU bez konieczności powrotu do CPU.

Poniższe sekcje pokazują, jak każda z tych trzech zmian wygląda w praktyce, po jakie nowe typy sięgają deweloperzy oraz jakie powody ich kształtu podaje dokumentacja Apple.

TL;DR

  • MTL4CommandQueue, MTL4CommandBuffer, MTL4RenderCommandEncoder, MTL4ComputeCommandEncoder, MTL4MachineLearningCommandEncoder to nowe typy.1 Pierwotne typy z prefiksem MTL pozostają. Adopcję prowadzi się stopniowo, mieszając obie rodziny.
  • Bufory poleceń otrzymują pamięć roboczą z osobnego MTL4CommandAllocator, co pozwala wielu wątkom równolegle kodować polecenia do wielu buforów. Pojedyncze wywołanie commit:count: przekazuje całą partię do kolejki.1
  • MTL4ComputeCommandEncoder zastępuje trzy wcześniejsze encodery: MTLBlitCommandEncoder, MTLComputeCommandEncoder oraz MTLAccelerationStructureCommandEncoder.1 Jeden encoder, trzy zadania.
  • MTL4MachineLearningCommandEncoder uruchamia modele Core ML wewnątrz bufora poleceń Metal.2 System wybiera GPU lub Apple Neural Engine dla każdego modelu. Tensory przenoszą wejścia i wyjścia; ten sam bufor poleceń łączy inferencję ML z pracą renderującą i obliczeniową.
  • Wiązanie zasobów przenosi się do tablic argumentów (MTL4ArgumentTable) zamiast metod wiązania na poziomie poszczególnych encoderów. Wszystkie zasoby są nieśledzone; synchronizację przeprowadza się jawnymi barierami.1

Dlaczego równoległa warstwa API

Sposób, w jaki Apple uzasadnia decyzję o równoległych typach, dosłownie z dokumentacji: „Metal 4 wprowadza kilka typów z prefiksem MTL4, które są całkowicie niezależne od pierwotnych typów MTL, które zastępują, takich jak MTL4CommandQueue w przeciwieństwie do MTLCommandQueue. Inne typy są wspólne dla wszystkich wersji Metal”.1

Sprawdzenie w czasie wykonania jest proste: aplikacja wykrywa, czy system obsługuje Metal 4, tworzy MTL4CommandQueue, jeśli tak, w przeciwnym razie sięga po MTLCommandQueue. Typ kolejki, który aplikacja utworzy, decyduje o tym, której rodziny typów używa reszta kodu renderującego.1

Druga połowa projektu pozwala obu rodzinom współpracować. MTLEvent i MTLSharedEvent synchronizują działania zarówno między instancjami MTLCommandQueue, jak i MTL4CommandQueue.1 Aplikacja zawierająca obszerną bazę kodu w Metal 1 może przełączyć pojedynczy podsystem na Metal 4, nie naruszając wzorców synchronizacji, na których opiera się reszta aplikacji.

To odpowiedź na pytanie, które deweloperzy aplikacji zadają od WWDC25: czy muszę przepisać swój kod Metal? Nie. Kształt API zachęca do stopniowej adopcji w obrębie poszczególnych podsystemów.

Wielowątkowe kodowanie buforów poleceń

Główne usprawnienie środowiska wykonawczego: pamięć bufora poleceń pochodzi z towarzyszącego typu, MTL4CommandAllocator, a nie z kolejki. Każdy wątek może kodować pracę do własnego bufora poleceń, używając własnego allocatora, a kolejka zatwierdza bufory zbiorczo.

Kształt API Apple: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)

Dwie zmiany operacyjne względem pierwotnego API:

Bufory poleceń są wielokrotnego użytku. Z dokumentacji Apple: „Każdy bufor poleceń można wielokrotnie wykorzystywać i przeznaczać do różnych celów w nieskończoność, rozpoczynając od nowa, kodując nowe polecenia i ponownie je zatwierdzając, zamiast alokować nowy bufor”.1 Wcześniejszy Metal wymagał świeżego, krótkotrwałego bufora dla każdego zatwierdzenia.

Brak automatycznego utrzymywania zasobów. „Każda instancja MTL4CommandBuffer nie tworzy silnych referencji do zasobów”.1 Zachowanie jest podobne do makeCommandBufferWithUnretainedReferences() ze starszego API. Aplikacje muszą jawnie zarządzać czasem życia zasobów, tak aby pozostawały żywe, dopóki GPU nie zakończy pracy.

Wzorzec frame-allocator, który Apple udostępnia w swoim przykładowym kodzie, używa jednego allocatora na każdą klatkę w locie (przykład używa trzech) i przełącza się między nimi w miarę przechodzenia klatek przez cykl kodowanie → renderowanie → wyświetlenie.1 Wywołanie reset() na allocatorze na początku każdej klatki zwraca jego pamięć do puli do ponownego użycia.

Ujednolicony encoder obliczeniowy

MTL4ComputeCommandEncoder to „nowy typ, który łączy funkcjonalność trzech swoich poprzedników: MTLBlitCommandEncoder, MTLComputeCommandEncoder, MTLAccelerationStructureCommandEncoder”.1

Wcześniejsze API wymagało od aplikacji przełączania typów encoderów w zależności od kształtu pracy: blit do kopiowania zasobów i transferów tekstur, compute do dispatchów kernelu, encoder struktur akceleracji do zarządzania sceną w ray tracingu. Metal 4 łączy te trzy w jedną warstwę. Aplikacja kodująca klatkę, która buduje strukturę akceleracji, wykonuje dispatch kernelu odszumiania i kopiuje teksturę do bufora prezentacji, może teraz wszystkie trzy operacje wykonać przez jeden typ encodera.

Encoder renderowania również otrzymał zmianę zachowania. MTL4RenderCommandEncoder obsługuje kodowanie przebiegu renderowania w wielu buforach poleceń, zawieszając pracę na końcu jednego encodera renderowania i wznawiając ją po rozpoczęciu kolejnego w sekwencji.1 Sposób ujęcia Apple: „Technika ta koncepcyjnie zastępuje protokół MTLParallelRenderCommandEncoder i upraszcza kodowanie przebiegu renderowania równolegle z wieloma wątkami, ponieważ każdy wątek może mieć własny encoder renderowania, zamiast wiązać je wszystkie z pojedynczym encoderem renderowania”.1

Wzorzec utrzymuje się: kodowanie równoległe staje się naturalnym kształtem, a API przestaje wymagać pojedynczego typu koordynującego.

Tablice argumentów zastępują wiązanie zasobów na poziomie encodera

Pierwotne API encodera Metal udostępniało metody takie jak setVertexBuffer(_:offset:index:) oraz setFragmentTexture(_:index:) na każdym encoderze, z osobnymi tabelami wiązań dla poszczególnych etapów wewnątrz encodera.1 Metal 4 zastępuje ten wzorzec jawną instancją MTL4ArgumentTable.

Sposób, w jaki Apple ujmuje korzyść projektową: „Encodery Metal 4 nie wymagają pamięci do przechowywania tabel wiązań dla każdego typu zasobu na każdym etapie. Każda tabela zużywa tylko tyle pamięci, ile potrzebuje na przechowanie swoich wiązań zasobów”.1

Przebieg: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])

Pojedyncza tablica argumentów może obsługiwać wiele encoderów, w tym encodery z różnych buforów poleceń, o ile zasoby, które wiąże, są odpowiednie dla wszystkich z nich. Dokumentacja Apple zaznacza: „Oszczędności pamięci i czasu wykonania kumulują się z każdym wspólnym zasobem dzielonym przez encodery i z każdym przypisaniem tablicy argumentów do nowego encodera”.1

Istnieje pewien kompromis. Wcześniejsze wersje Metal obsługiwały śledzenie zagrożeń (hazard tracking) dla tekstur i sterty (heaps), które zgłaszały taką potrzebę poprzez MTLTextureDescriptor.hazardTrackingMode lub MTLHeapDescriptor.hazardTrackingMode.1 W Metal 4 „framework traktuje wszystkie zasoby jako nieśledzone. Trzeba zsynchronizować etapy potoku, które mogą równolegle uzyskać dostęp do zasobu, jeśli którykolwiek z shaderów w tych potokach go modyfikuje”.1 Aplikacje dodają jawne bariery, aby opóźnić etap, aż wcześniejszy się zakończy. To więcej kodu niż starsze opt-in śledzenie, w zamian za przewidywalną wydajność i niższy narzut środowiska wykonawczego.

Uczenie maszynowe jako pełnoprawny przebieg

MTL4MachineLearningCommandEncoder to architektonicznie najistotniejszy dodatek. Sposób ujęcia Apple:2

„Metal 4 wprowadza możliwość wydajnego uruchamiania modeli CoreML w ramach przepływu pracy Metal. Jest to przydatne dla aplikacji, które potrzebują zastosować wynik modelu w kontekście Metal, na przykład renderując scenę lub uruchamiając dispatch obliczeniowy”.

Dwie rzeczy dzieją się jednocześnie. Po pierwsze, inferencja ML działa na osi czasu GPU, w tym samym buforze poleceń co praca renderująca i obliczeniowa. Aplikacja nie wraca przez CPU między inferencją modelu a przebiegiem renderowania, który konsumuje wynik. Po drugie, system wybiera silnik inferencji: „System automatycznie wybiera silnik inferencji, taki jak GPU urządzenia lub Apple Neural Engine (ANE), dla każdego modelu uczenia maszynowego. GPU może wykonywać dodatkową, niezależną pracę renderującą lub obliczeniową razem z GPU, gdy system zdecyduje się uruchomić model na ANE”.2

Przepływ deweloperski:2

  1. Konwersja modelu Core ML do pakietu Metal ML za pomocą metal-package-builder, dołączonego do narzędzi Xcode 26.
  2. Dodanie pakietu Metal ML do projektu Xcode. Xcode kompiluje go do biblioteki Metal podczas budowania.
  3. W czasie wykonania aplikacja tworzy MTL4MachineLearningPipelineState z tej biblioteki.
  4. Encoder przyjmuje stan potoku, MTLHeap na pamięć roboczą oraz instancje MTLTensor jako wejścia i wyjścia.

MTLTensor to nowy typ zasobu dla wielowymiarowych tablic danych.2 Dokumentacja Apple zaznacza, że typ ten współpracuje z popularnymi typami wag ML, takimi jak int8 i fp16. Tensory przenoszą wejścia do modelu i wyjścia z niego; dla danych przejściowych między wywołaniami inferencji Metal Shading Language dodaje typy tensorowe, które żyją bezpośrednio na GPU:2

  • tensor_handle: uchwyt do MTLTensor utworzonego na CPU
  • tensor_inline: tensor zdefiniowany na GPU jako widok na tensor lub bufor
  • cooperative_tensor: tensor, który rozdziela swoje elementy między wątki współpracujące z nim

Typ cooperative_tensor to przypadek wrażliwy na opóźnienia: „Tensory kooperatywne zapewniają tymczasową pamięć dla tensorów przejściowych poprzez równomierne rozdzielenie ich danych między wątki, które z tym tensorem pracują. Taki rozkład pamięci redukuje przepustowość pamięci dzięki alokacji z prywatnych przestrzeni adresowych wątku lub grupy wątków, co jest istotne dla algorytmów uczenia maszynowego krytycznych pod względem opóźnień”.2

MSL otrzymał także operatory tensorowe działające bezpośrednio w kodzie shadera: konwolucję, mnożenie macierzy, redukcję.2 Aplikacje, które potrzebują manipulować wagami między przebiegami inferencji, mogą to zrobić bez kopiowania tensorów z powrotem do pamięci CPU ani uruchamiania osobnego przebiegu obliczeniowego; operatory wpisują się w zwykłe kernele MSL.

Warto przytoczyć jedną granicę: „Encodery uczenia maszynowego uruchamiają modele Core ML, ale nie mogą budować nowych sieci ani modyfikować warstw i wejść istniejących; do tych zadań patrz Core ML i Metal Performance Shaders Graph”.2 Encoder ML w Metal 4 służy do uruchamiania inferencji w gotowych aplikacjach, a nie do trenowania ani konstrukcji modelu.

Co Metal 4 oznacza dla stosu Apple

Trzy wnioski dla deweloperów aplikacji planujących adopcję Metal 4:

  1. Adopcja stopniowa, podsystem po podsystemie. Równoległe typy z prefiksem MTL4 oraz interoperacyjność oparta na zdarzeniach z pierwotnym API są zaprojektowane pod migrację częściową. Warto wybrać podsystem o wyraźnej presji wydajnościowej (ścieżkę renderowania, potok obliczeniowy, pętlę inferencji modelu) i przemigrować go w pierwszej kolejności.1
  2. Kodowanie wielowątkowe to nowa norma. Wzorzec allocator-na-wątek, zbiorcze przekazywanie commit:count: oraz mechanizm zawieszania/wznawiania przebiegu renderowania zakładają, że kodowanie równoległe to kształt, którego będą używać wydajne aplikacje. Kodowanie jednowątkowe nadal działa, ale zyski środowiska wykonawczego frameworka kumulują się przy adopcji wielowątkowej.1
  3. ML działa w tym samym buforze poleceń co cała reszta. Dla aplikacji łączących inferencję modelu na urządzeniu z renderowaniem lub obliczeniami (potoki przetwarzania obrazu filtrujące przez model Core ML, efekty czasu rzeczywistego zależne od wyjścia klasyfikatora, doświadczenia AR, których renderowanie zależy od wyniku inferencji per-klatka) zdolność do zakodowania inferencji ML w tym samym buforze poleceń, w którym znajduje się przebieg renderowania konsumujący wynik, jest zmianą jakościową.2

Dodatki do Metal Shading Language zasługują na osobne omówienie. Typy i operatory tensorowe w kodzie shadera, w połączeniu z deskryptorami operacji dla operacji niestandardowych, zmieniają to, co kernel Metal może wyrazić. To temat na osobny wpis.

Pełny klaster Apple Ecosystem: Foundation Models on-device LLM — framework działający na szczycie tego stosu; cykl życia własnych adapterów — specjalizacja zarządzana przez dewelopera; Core ML on-device inference — framework ML, którego modele Metal 4 uruchamia teraz wbudowanie. Hub znajduje się w Apple Ecosystem Series.

FAQ

Czy Metal 4 to oddzielny framework od Metal?

Nie. Framework to nadal Metal. Dokumentacja Apple opisuje Metal 4 jako „rdzeniowe API Metal 4”: zestaw nowych typów z prefiksem MTL4, dostarczanych obok pierwotnych typów MTL w tym samym frameworku.1 Aplikacje stopniowo przyjmują nowe typy, wykrywając obsługę Metal 4 w czasie wykonania i tworząc odpowiedni typ kolejki.

Czy potrzebuję iOS 26, aby używać Metal 4?

Framework Metal obsługuje iOS 8+, ale rdzeniowe API Metal 4 to wersja, którą Apple wprowadził na WWDC25. Należy uruchomić wykrywanie w czasie wykonania i utworzyć MTL4CommandQueue lub MTLCommandQueue w zależności od tego, co obsługuje urządzenie.1

Jaka jest relacja między przebiegami ML w Metal 4 a Foundation Models?

Działają na różnych stosach. MTL4MachineLearningCommandEncoder uruchamia modele Core ML skonwertowane do pakietów Metal ML, w tym samym buforze poleceń co praca renderująca i obliczeniowa.2 Foundation Models to oddzielny framework, który uruchamia model językowy systemu Apple na urządzeniu z własnym sesyjnym API, omówionym we wpisie Foundation Models on-device LLM. Te dwa rozwiązania są komplementarne: aplikacja może użyć Foundation Models do generowania tekstu, a przebiegów ML w Metal 4 do inferencji modeli wizyjnych lub audio wewnątrz pętli renderowania.

Dlaczego encoder obliczeniowy jest teraz ujednolicony?

Dokumentacja Apple łączy MTLBlitCommandEncoder, MTLComputeCommandEncoder i MTLAccelerationStructureCommandEncoder w MTL4ComputeCommandEncoder.1 Uzasadnienie ma charakter operacyjny, nie wyłącznie wydajnościowy: pojedynczy typ encodera dla pracy compute, blit i struktur akceleracji upraszcza zarządzanie potokiem i zmniejsza rotację encoderów w aplikacjach przeplatających te trzy.

Czy opcje store-action są nadal dostępne w Metal 4?

Nie dla MTL4RenderCommandEncoder. Dokumentacja Apple zaznacza: „Opcje store-action (zob. MTLStoreActionOptions) nie są dostępne, ponieważ nie mają zastosowania do GPU Apple silicon”.1 Decyzja architektoniczna odzwierciedla, że Apple celuje rdzeniowym API Metal 4 wyłącznie w GPU.

Czy muszę używać tablic argumentów?

W Metal 4 — tak. Protokoły encodera nie udostępniają metod wiązania na poziomie poszczególnych zasobów. Wiązania zasobów konfiguruje się w MTL4ArgumentTable i przypisuje tę tablicę do jednego lub więcej etapów encodera.1 Korzyść środowiska wykonawczego polega na tym, że tablica alokuje pamięć tylko na faktycznie używane wiązania, zamiast utrzymywać tabele o stałym rozmiarze dla każdego etapu na każdym encoderze.

Bibliografia


  1. Apple Developer, „Understanding the Metal 4 core API”. Porównanie hierarchii typów (MTL4 vs MTL), zachowanie kolejki i bufora poleceń, wzorzec command allocatora, ujednolicenie encoderów, tablice argumentów, śledzenie zagrożeń, zawieszanie/wznawianie przebiegów renderowania. Pobrano 2026-05-04. 

  2. Apple Developer, „Machine learning passes”. MTL4MachineLearningCommandEncoder, MTLTensor, typy tensorowe MSL (tensor_handle, tensor_inline, cooperative_tensor), metal-package-builder, wybór silnika inferencji przez system (GPU/ANE), operatory tensorowe MSL. Pobrano 2026-05-04. 

Powiązane artykuły

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 czytania

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 czytania

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 czytania