multithreading - 来自子 CPU 线程的 Vulkan Compute 调度
问题描述
Vulkan Compute 可以从子 CPU 线程分派,还是必须从主线程分派?我认为这不可能在 Unity 中从子线程调度计算着色器,我想知道它是否可以在虚幻引擎中完成。
解决方案
这取决于您所说的“调度”和“主线程”是什么意思。
vkCmdDispatch
,正如 " Cmd
" 前缀所暗示的,将命令放入命令缓冲区。这可以在任何线程上调用,只要VkCommandBuffer
对象不会同时vkCmd
调用其他函数(通常,您为单个线程保留特定的命令缓冲区)。因此,根据一个定义,您可以从其他线程“分派”计算操作。
当然,在命令缓冲区中记录命令实际上并没有做任何事情。只有当您通过vkQueueSubmit
. 就像vkCmdDispatch
,您在哪个线程上调用该函数并不重要。但是,就像 一样vkCmdDispatch
,阻止多个线程同时访问同一个对象确实很重要。VkQueue
现在,您不必为此使用单个线程VkQueue
;您可以锁定VkQueue
某种互斥锁,以便一次只有一个线程可以拥有它。因此,创建 CB 的线程可以提交自己的工作。
但是,忽略任务通常需要按顺序插入队列的事实(一个任务可能会生成一些图形任务需要等待的计算数据,因此图形任务 CB必须在计算 CB 之后),有一个更大的问题。vkQueueSubmit
需要很长时间。如果你看一下这个函数,它可以插入任意数量的 CB,并且它具有多个批次的能力,每个批次都由信号量和栅栏保护以进行同步。因此,强烈建议您尽可能少vkQueueSubmit
地调用,因为每次调用都会产生一定数量的开销,这与您排队的 CB 数量无关。
规范本身甚至对此有警告。
因此,构建应用程序的典型方式是将任务分配给可用的 CPU 线程,然后这些任务构建命令缓冲区。一个特定的线程将被指定为队列的所有者。该线程可能会执行一些 CB 构建,但一旦完成,它将等待其他任务完成并从其他线程收集所有 CB。收集后,该线程会将vkQueueSubmit
它们分成适当的批次。
您可以将该线程称为“主线程”,但 Vulkan 本身并不真正关心哪个线程“拥有”队列。它当然不必是您进程的初始线程。
推荐阅读
- javascript - react-redux 提供者的上下文实例属性是什么?
- git - 如何根据常规提交规范对 UI 更改进行分类?
- android - Logcat 不断滚动,永不停止
- amazon-web-services - AWS 目标群体在没有数据的情况下变得不健康
- blazor - 在循环中正确使用序列参数
- css - CSS,如果未找到字体并使用替代品,则自动更改大小等样式
- regex - 使用连续 \d 和 \w 时了解正则表达式的行为
- sharepoint - SharePoint Online 的套件栏中缺少搜索框
- python - 错误:“int”对象没有属性“split”
- c# - 请求服务器时记录错误,收到一个不成功的 HTTP 代码完成响应正文:{“error”:“consent_required”}