【发布时间】:2021-03-24 19:42:03
【问题描述】:
在彻底阅读 Vulkan 规范中关于同步的语言后,我试图确认特定场景不会引入数据竞争。考虑下面的 sn-p,第二个队列中的工作提交从第一个提交读取工作结果,主机在第一个提交之间等待:
VkFence first_work_fence = ... (unsignaled);
VkSubmitInfo first_work_submit_info = ... (no semaphore wait / signal);
vkQueueSubmit(chosen_queue, 1, &first_work_submit_info, first_work_fence); // (1)
...
vkWaitForFences(device, 1, &first_work_fence, VK_TRUE, UINT64_MAX); // (2)
...
VkSubmitInfo reads_first_work_submit_info = ... (no semaphore wait / signal);
vkQueueSubmit(chosen_queue, 1, &reads_first_work_submit_info, ...); // (3)
根据我对规范的阅读,以上三个步骤的情况如下:
- 创建一个fence信号操作,这是一个内存依赖,它的第一个同步范围覆盖了提交命令中的所有工作,第一个访问范围覆盖了设备执行的所有内存访问(spec 7.3);作为执行内存依赖的操作,它会生成可用性操作,使操作的第一个访问范围内的写入对设备可用 (spec appendix B)
- 在栅栏上等待确保栅栏信号操作已经发生,从而使第一次提交的写入可用,但根据上述内容不一定对设备域可见
- “
vkQueueSubmit执行...具有设备域的源范围和设备上所有代理和引用的目标范围的可见性操作。” (spec appendix B)
这似乎意味着在 (3) 中提交的工作可以访问在 (1) 中提交的工作的所有副作用,而无需进一步同步或显式内存可见性操作(例如屏障)。这是正确的吗?
【问题讨论】: