Multithreading 如何同步“vkMapMemory”?

Multithreading 如何同步“vkMapMemory”?,multithreading,vulkan,Multithreading,Vulkan,国家: 在返回主机可访问指针之前,vkMapMemory不会检查设备内存当前是否正在使用。应用程序必须确保在主机读取或写入该区域之前,任何先前提交的写入该区域的命令都已完成,并且在主机写入该区域之前,任何先前提交的从该区域读取的命令都已完成 不幸的是,它与似乎还不存在的东西有联系。我想知道我将如何同步这个 基本上我需要担心两件事 只有1个线程同时访问同一范围 Gpu当前未尝试读取范围 我看到的唯一真正的同步方法是使用线程安全列表。每次您想要写入/读取该缓冲区,您必须将当前尝试读取或写入的内存

国家:

在返回主机可访问指针之前,vkMapMemory不会检查设备内存当前是否正在使用。应用程序必须确保在主机读取或写入该区域之前,任何先前提交的写入该区域的命令都已完成,并且在主机写入该区域之前,任何先前提交的从该区域读取的命令都已完成

不幸的是,它与似乎还不存在的东西有联系。我想知道我将如何同步这个

基本上我需要担心两件事

  • 只有1个线程同时访问同一范围
  • Gpu当前未尝试读取范围
我看到的唯一真正的同步方法是使用线程安全列表。每次您想要写入/读取该缓冲区,您必须将当前尝试读取或写入的内存范围添加到该线程安全列表中

这意味着当您想要访问该缓冲区时,您需要锁定该列表并搜索您试图访问的范围


这就是同步vkMapMemory的方式吗?或者还有其他方法吗?

gpu尝试访问映射内存的唯一时间是提交访问该内存的命令缓冲区时。在发出相关的
vkFence
信号之前,该内存将一直处于使用状态

一个完全通用的解决方案是跟踪gpu的每个内存访问,并用一个开始/结束对围绕每个CPU映射的内存访问,该对将在适当的围栏上等待,并根据需要调用flush/invalidate。这是大量的状态跟踪和大量潜在的阻塞调用

但是,对于持久性网格/纹理数据,您只需将内存写入暂存缓冲区,然后复制到设备本地非主机可见缓冲区。你不应该经常需要它,所以一个单独的栅栏来跟踪它的副本是否在飞行中就足够了。或者,对于只需要保存一帧(每个对象变换)的数据,可以使用环形缓冲区。回读GPU遮挡测试或计算结果时,可以使用环形缓冲区

我希望你能看到这种模式的出现。只需使用几个映射的环形缓冲区,并非常清楚gpu何时使用它们,然后只需为每个环形缓冲区保留一个vkFence+offset+size的小数组,以确保不会发生数据危险