金属渲染产生奇怪的竞争条件

Metal render producing odd race condition

我在 Xcode 9.4.1 中打开了线程清理程序,现在我在我的旋转缓冲区(最大大小为 2)上收到了一个奇怪的竞争条件警告。我原以为在这里正确使用信号量会消除这个问题。我应该提到这个缓冲区来自单独 'first' MTKView 中另一个渲染编码的输出。我在第二个下游视图中通过 dispatch_semaphore_create(1) 初始化了一个信号量。

在我的第一个 MTKView 中,我在提交后按如下方式获取渲染纹理,然后使用下游视图的信号量将其排入下游缓冲区:

[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
//[commandBuffer waitUntilCompleted]; // (doesn't matter if this is in or out)
...
id obj = [self.renderedQueue firstObject];
for (MonitorMTKView *v in self.downstreamOutputs) {
   dispatch_semaphore_wait(v.bufferSemaphore,DISPATCH_TIME_FOREVER);
   [v.textureQueue addObject:inputTexture];
   if ([v.textureQueue count]>2)
      [v.textureQueue removeObjectAtIndex:0];
   dispatch_semaphore_signal(v.bufferSemaphore);
}

现在进入下游 MTKView 中的渲染循环。我提交命令缓冲区并且我有这个完成处理程序:

__block __weak __typeof__(self) weakSelf = self;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
   dispatch_semaphore_wait(weakSelf.bufferSemaphore, DISPATCH_TIME_FOREVER);
   id obj = [weakSelf.textureQueue firstObject];

**// thread sanitizer issue on this next line of code "Race on a library object detected" **
   [weakSelf.textureQueue removeObject:obj];

   dispatch_semaphore_signal(weakSelf.bufferSemaphore);
}


为什么围绕信号量保护的竞争条件? 我做错了什么吗?。缓冲区本身不是基于 GPU 的,因此不会有干扰。

一种思路是对其进行三重缓冲,但这并不能缓解问题,所以我认为它不会干扰 GPU。

Apple Metal 文档指出您应该使用 3 个缓冲区以避免填充缓冲区和传递给 GPU 之间的竞争条件。