如果您打算并行记录,那么您最好不要为每个线程设置一个单独的池,不是吗?
我看不出每个线程有一个单独的池如何“在并行记录时扼杀命令池的全部目的”。确实,它对它有很大帮助,因为每个线程都可以按照它认为合适的方式管理自己的命令池。
考虑一下描述符池和命令池之间的结构差异。使用描述符池,您基本上可以准确地告诉它您将从其中分配什么。VkDescriptorPoolCreateInfo
提供详细信息,允许实现预先准确分配您将为每个池使用的内存量。而且您不能从描述符池中分配更多。
相比之下,VkCommandPoolCreateInfo
包含……什么都没有。哦,你告诉它命令缓冲区可以是主要的还是次要的。您说命令缓冲区是否会经常重置或持久化。还有其他几件事。但除此之外,您对命令缓冲区的内容只字未提。您甚至没有提供有关您将分配多少缓冲区的信息。
描述符池旨在固定:根据需要分配,但最多在构建时设置数量。命令缓冲区旨在非常动态:根据您的特定用例的需要分配。
把它想象成每个池都有自己的 malloc/free。由于用户被迫同步对池及其缓冲区的访问,这意味着每个vkCmd*
函数在分配内存时都不需要这样做。这使得命令构建更快。这有助于线程。当一个线程决定重置它的命令池时,它不必锁定任何互斥锁或任何其他类似的东西来做到这一点。
每个线程拥有一个命令池在概念上没有任何问题。实际上,每个线程有两个(双缓冲)更有意义。
我个人不知道您为什么不预先录制所有内容。
因为您不是在制作静态技术演示。
我猜这是因为缺乏经验,但我想象并行记录看起来像“线程 2-N 记录辅助命令缓冲区,线程 1 在一个主命令缓冲区中调用所有这些”,在这种情况下只有一个命令每个线程的缓冲区。这就是为什么我说它扼杀了命令池的目的,因为您只为每个池进行一次分配。
这当然是一种可行的并行记录命令缓冲区的形式。但是有两件事你错过了。
虽然这肯定是并行记录的一种形式,但它不是唯一的。如果您正在执行延迟渲染,则为照明通道构建 CB 的线程将比负责(部分)几何通道的线程之一更快地完成其工作。因此,一个设计良好的多线程系统必须根据需要将工作分配给线程,而不是基于某些固定的东西安排。因此,单个线程通常最终会构建多个命令缓冲区。
即使不是这样,你也会忘记缓冲。当需要为下一帧构建 CB 时,您不能只覆盖现有的。毕竟,他们可能还在排队工作。所以每个线程至少需要两个CB;当前正在执行的和当前正在构建的。
即使不是这样,命令池也会分配与 CB 关联的所有内存。我将它们类比为malloc/free
. 即使您只使用具有特定池的单个 CB,该 CB 的分配(可能由于任何vkCmd*
功能而发生)永远不必与另一个线程同步这一事实是一件好事。
所以不,这绝不会抑制使用多个线程构建 CB 的能力。