Metal and Swift Concurrency

Hi,

Introducing Swift Concurrency to my Metal app has been a bit challenging as Swift Concurrency is limited by the cooperative thread pool. GPU work is obviously not CPU bound and can block forward moving progress, especially when using waitUntilCompleted on the command buffer. For concurrent render work this has the potential of under utilizing the CPU and even creating dead locks.

My question is, what is the Metal's teams general recommendation when it comes to concurrency? It seems to me that Dispatch or OperationQueues are still the preferred way for Metal bound tasks in order to gain maximum performance?

To integrate with Swift Concurrency my idea is to use continuations that kick off render jobs via Dispatch or Queues? Would this be the best solution to bridge async tasks with Metal work?

Thanks!

You can use Swift concurrency for your app’s own internal parallelization, but the current best practices for frame pacing (CAMetalDisplayLink and LayerRenderer/cp_layer_renderer) use explicit threading.

That makes sense. Exactly what are you referring to when you mean explicit threading? Would you recommend using continuations to bridge tasks from the higher level parts of the app to the render engine?

In my use case I'm doing a lot of Core Image render tasks and displaying the results in MTKViews.

For example, the Compositor Services documentation shows an example of spawning a thread to run your renderer. For CAMetalDisplayLink, you must add the display link to a CFRunLoop.

Is the best practice of using the Thread class based on that it has less overhead and in turn offers better performance compared to Dispatch or is there other reasoning behind this?

What would the downsides be of using a higher level API?

Metal and Swift Concurrency
 
 
Q