3

Looking at the code provided by Apple for triple buffering of Metal buffer and texture resources, it seems very strange that the use of a semaphore could block the main thread in code like the following. This is from CPU and GPU Synchronization.

- (void)drawInMTKView:(nonnull MTKView *)view
{
  dispatch_semaphore_t inFlightSemaphore = self.inFlightSemaphore;
  dispatch_semaphore_wait(inFlightSemaphore, DISPATCH_TIME_FOREVER);

  id <MTLCommandBuffer> commandBuffer = [mrc.commandQueue commandBuffer];

  __block dispatch_semaphore_t block_sema = inFlightSemaphore;
  [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer)
   {
     dispatch_semaphore_signal(block_sema);
   }];

  // Metal render commands
}

How would invoking dispatch_semaphore_wait() not block the main thread in a call to drawInMTKView?

MoDJ
  • 4,309
  • 2
  • 30
  • 65

1 Answers1

2

It absolutely can block the drawing thread, but in most applications this should happen rarely, if at all. When drawing is being driven by a display link, as is the case by default with MTKView, draw callbacks arrive every ~16ms. Since the counting semaphore allows up to three frames to be encoded before blocking, the first of these frames is almost certain to have finished executing (i.e., within 50 ms) before a subsequent frame callback arrives, and therefore the wait call doesn't entail a block. If encoding or execution takes on average longer than the nominal frame duration, the wait call will block until the most recent non-completed frame completes.

warrenm
  • 31,094
  • 6
  • 92
  • 116
  • Okay, it seems useful in the case where everything is very fast. But, what happens then if 2 or 3 views start to fall behind? These will end up blocking the main thread over and over again and that will interrupt the event loop processing, right? – MoDJ Jan 05 '18 at 22:43
  • Is the same triple buffering approach also advised for Metal performance shaders? And, therefore is it better to execute them on a low priority queue? – Deepak Sharma May 06 '18 at 12:28
  • @DeepakSharma That's probably best asked as a new question. Broadly speaking, unless you're doing a truly huge number of MPS operations, encoding them is unlikely to take a significant amount of CPU time, but that's only part of the equation. – warrenm May 07 '18 at 03:53
  • Ok I would put that as a new question and submit the link here – Deepak Sharma May 07 '18 at 11:32
  • @warrenm Here is the link - https://stackoverflow.com/questions/50213499/mtlbuffer-allocation-cpu-gpu-synchronisation – Deepak Sharma May 07 '18 at 11:49