可以在数组中创建/分配一些Vulkan对象(例如vkPipelines,vkCommandBuffers)(使用size + pointer参数)。一目了然,这似乎是为了使用常见的使用模式更容易编码。但在某些情况下(例如:创建C ++ RAII包装器时),一次创建一个包装器就更好了。当然,实现这一目标很简单。
但是,我想知道这样做是否有任何重大缺点?
(我想这可能会因创建的实际对象类型而异 - 但我认为对每个对象提出相同的问题并不是一个好主意)
假设在这两种情况下,对象很可能以第一次创建 - 最后被破坏的方式创建,并且 - 当对象被单独创建和销毁时 - 这可能会在循环中发生。
另请注意:
我是否应该修改我的RAII包装器以允许基于数组的创建/销毁?例如,它会节省内存(显着)吗?单一创作会降低性能吗?
答案 0 :(得分:2)
请记住,vkPipeline
创建不需要外部同步。这意味着该过程将处理自己的互斥体等等。因此,尽可能避免锁定这些内部互斥锁是有意义的。
此外,该过程慢。因此能够批量处理并将其执行到另一个线程非常有用。
创建命令缓冲区没有这些问题。所以,你应该随意分配你需要的任何CB。但是,多次创建永远不会损害性能,它可能会有所帮助。所以没有理由避免它。
答案 1 :(得分:1)
Vulkan是围绕现代图形硬件设计的API。如果您知道要预先创建一定数量的对象,则应使用批处理函数(如果存在),因为驱动程序可能能够优化创建/分配,从而可能获得更好的性能。
答案 2 :(得分:1)
可能(或可能没有)更好的性能(取决于驱动程序和工作负载的类型)。但是,显然潜力可以提高性能。
如果在应用程序中创建一个或十个命令缓冲区,则无关紧要。
对于大多数情况,它将低于5%。所以,如果你不关心它(例如你的应用程序已经运行500 FPS),那么无关紧要。
然后,C ++是一种多功能语言。我认为这不是问题。你只需要一个静态成员函数或一个构造/初始化N个对象的类(可能有一个模式名称)。
破坏可能更棘手。您可以再次使用会破坏N个对象的静态成员函数。但它不会自动调用,并且周围有空/外壳对象很烦人。并且仍然会在VK_NULL_HANDLE
上调用析构函数。还有一个问题是,池重置或破坏会使所有命令缓冲区C ++对象无效,因此可能无法干净/简单地执行此操作。