金属渲染产生奇怪的竞争条件
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 之间的竞争条件。
我在 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 之间的竞争条件。