来自子 CPU 线程的 Vulkan Compute 调度
Vulkan Compute dispatch from a child CPU thread
Vulkan Compute 可以从子 CPU 线程调度,还是必须从主线程调度?我认为在 Unity 中从子线程分派计算着色器是不可能的,我想知道是否可以在 Unreal Engine.
中完成
这取决于你所说的 "dispatch" 和 "main thread" 的意思。
vkCmdDispatch
,如“Cmd
”前缀所示,将命令放入命令缓冲区。这可以在任何线程上调用,只要 VkCommandBuffer
对象不会同时调用其他 vkCmd
函数(通常,您为单个线程保留特定的命令缓冲区)。因此,根据一个定义,您可以 "dispatch" 从其他线程计算操作。
当然,在命令缓冲区中记录命令实际上没有任何作用。只有当您通过 vkQueueSubmit
将这些 CB 排队时,才会执行命令。就像 vkCmdDispatch
一样,在哪个线程上调用该函数并不重要。但是,与 vkCmdDispatch
一样, 重要的是 可以防止多个线程同时访问同一个 VkQueue
对象。
现在,您不必为此使用单个线程 VkQueue
;您可以将 VkQueue
锁定在某种互斥锁后面,这样一次只有一个线程可以拥有它。因此,创建 CB 的线程可以提交自己的工作。
然而,忽略任务往往需要按顺序插入队列的事实(一个任务可能会产生一些图形任务需要等待的计算数据,因此图形任务CB must be after the compute CB),这是一个更大的问题。 vkQueueSubmit
需要 长时间 。如果你看一下这个函数,它可以插入任意多的 CB,并且它有多个批次的能力,每个批次都由信号量和栅栏保护以进行同步。因此,强烈 鼓励您进行尽可能少的 vkQueueSubmit
调用,因为每次调用都有一定的开销,与您的 CB 数量无关正在排队。
规范本身甚至对此有警告。
因此,典型的应用程序构建方式是将任务分包给可用的 CPU 线程,这些任务构建命令缓冲区。一个特定的线程将被指定为队列的所有者。该线程可能会执行一些 CB 构建,但一旦完成,它将等待其他任务完成并从其他线程收集所有 CB。收集后,该线程将 vkQueueSubmit
分批处理。
您可以将该线程称为 "main thread",但 Vulkan 本身并不真正关心 哪个 线程 "owns" 队列。它当然不必是您进程的初始线程。
Vulkan Compute 可以从子 CPU 线程调度,还是必须从主线程调度?我认为在 Unity 中从子线程分派计算着色器是不可能的,我想知道是否可以在 Unreal Engine.
中完成这取决于你所说的 "dispatch" 和 "main thread" 的意思。
vkCmdDispatch
,如“Cmd
”前缀所示,将命令放入命令缓冲区。这可以在任何线程上调用,只要 VkCommandBuffer
对象不会同时调用其他 vkCmd
函数(通常,您为单个线程保留特定的命令缓冲区)。因此,根据一个定义,您可以 "dispatch" 从其他线程计算操作。
当然,在命令缓冲区中记录命令实际上没有任何作用。只有当您通过 vkQueueSubmit
将这些 CB 排队时,才会执行命令。就像 vkCmdDispatch
一样,在哪个线程上调用该函数并不重要。但是,与 vkCmdDispatch
一样, 重要的是 可以防止多个线程同时访问同一个 VkQueue
对象。
现在,您不必为此使用单个线程 VkQueue
;您可以将 VkQueue
锁定在某种互斥锁后面,这样一次只有一个线程可以拥有它。因此,创建 CB 的线程可以提交自己的工作。
然而,忽略任务往往需要按顺序插入队列的事实(一个任务可能会产生一些图形任务需要等待的计算数据,因此图形任务CB must be after the compute CB),这是一个更大的问题。 vkQueueSubmit
需要 长时间 。如果你看一下这个函数,它可以插入任意多的 CB,并且它有多个批次的能力,每个批次都由信号量和栅栏保护以进行同步。因此,强烈 鼓励您进行尽可能少的 vkQueueSubmit
调用,因为每次调用都有一定的开销,与您的 CB 数量无关正在排队。
规范本身甚至对此有警告。
因此,典型的应用程序构建方式是将任务分包给可用的 CPU 线程,这些任务构建命令缓冲区。一个特定的线程将被指定为队列的所有者。该线程可能会执行一些 CB 构建,但一旦完成,它将等待其他任务完成并从其他线程收集所有 CB。收集后,该线程将 vkQueueSubmit
分批处理。
您可以将该线程称为 "main thread",但 Vulkan 本身并不真正关心 哪个 线程 "owns" 队列。它当然不必是您进程的初始线程。