Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory management 在性能方面,应如何正确使用暂存缓冲区?_Memory Management_Buffer_Vulkan - Fatal编程技术网

Memory management 在性能方面,应如何正确使用暂存缓冲区?

Memory management 在性能方面,应如何正确使用暂存缓冲区?,memory-management,buffer,vulkan,Memory Management,Buffer,Vulkan,Vulkan API的暂存缓冲区应该如何正确使用?因为将顶点数据保存到暂存缓冲区,而不是复制到GPU中的顶点缓冲区,似乎比直接将顶点提交到顶点缓冲区需要更长的步骤。这是一个Minecraft克隆程序,因此将有大量顶点数据(也有索引数据)和动态块加载,那么是否有其他类型的缓冲区或缓冲方法可以从中受益 即使这样,使用单独的设备线程或跨设备线程似乎也比直接将顶点动态提交到顶点缓冲区要慢。我目前还不清楚使用传统的直接顶点缓冲区和分段缓冲区的优缺点 我现在关注的是在绘图和演示之前使用一次暂存缓冲区。似乎缺

Vulkan API的暂存缓冲区应该如何正确使用?因为将顶点数据保存到暂存缓冲区,而不是复制到GPU中的顶点缓冲区,似乎比直接将顶点提交到顶点缓冲区需要更长的步骤。这是一个Minecraft克隆程序,因此将有大量顶点数据(也有索引数据)和动态块加载,那么是否有其他类型的缓冲区或缓冲方法可以从中受益

即使这样,使用单独的设备线程或跨设备线程似乎也比直接将顶点动态提交到顶点缓冲区要慢。我目前还不清楚使用传统的直接顶点缓冲区和分段缓冲区的优缺点


我现在关注的是在绘图和演示之前使用一次暂存缓冲区。似乎缺少讨论上述问题的论坛或文章。

实现高性能的确切机制在很大程度上取决于硬件的细节和预期的数据更新频率

暂存缓冲区仅与具有多个设备内存池的GPU相关。集成GPU通常只有一个内存池,因此转移顶点数据没有任何意义(由于平铺,纹理仍然需要转移)

因此,在具有多个内存池的设备中,您首先需要了解的是您的选项。在多内存GPU(又名:拥有自己内存的GPU)中,一个或多个池将标记为
DEVICE\u LOCAL
。这意味着表示具有GPU操作的最快可能访问时间的内存

但设备本地内存(通常)不能直接从CPU访问;因此,需要分期付款

但是,非设备本地的内存可以用于GPU任务。也就是说,GPU可以直接从CPU可访问的内存中读取某些类型的操作。您可以询问特定的内存类型是否可用作顶点数据的源内存

如果CPU可访问,非设备本地内存可用于顶点数据,那么您现在有一个真正的选择:从哪个池读取?您是否通过PCI-e总线读取顶点数据?还是将顶点数据传输到更快的内存中,然后从中读取

在每个帧都动态生成顶点数据的情况下,我可能会说您应该默认不分段(但仍然应该在适用的硬件上对其进行分析)

如果你在做一些数据流,当摄像机在场景中移动时,你正在加载世界数据,那么我认为最好的办法是将数据传输到设备本地内存。您使用数据的频率比执行传输操作的频率要高得多,并且您应该能够在几个传输调用中转储整个数据块

但您的用例是关于间歇性数据生成的。即使播放机不断放置块,也可能会重复使用相同的数据来渲染多个帧。即使放置了一个块,您也只需更改数据的一部分。每个传输操作都有一定程度的开销,因此进行一系列小的传输可能会使事情变得缓慢

因此,很难说哪个更好;您应该在各种硬件上对其进行分析,以了解性能

另外,请注意,AMD硬件往往有一个256MB的特殊池,既可以访问CPU,也可以本地设备。据推测,CPU有一些快速通道将其数据写入设备内存。此内存池专为流式使用而设计,因此非常适合您的需要(假设256MB有足够的空间;所有AMD硬件在此池中使用相同的大小,而不管该卡有多少RAM)。

简而言之:

  • 登台只是将数据从CPU复制到GPU内存的一种方式

  • 若数据在CPU内存中,它将通过PCI-e读取,并在访问时由GPU缓存

  • PCI-e具有相对有限的吞吐量和一些延迟

  • 无意识地复制每一帧都是无用的,并且会增加开销

  • 因此:

  • 如果内存经常被CPU改变(比如摄像机矩阵、球员位置),那么就让它在CPU内存中

  • 如果数据很少/只有一小部分被CPU修改,则将其转移到GPU

  • 就你而言:

  • 包含体素数据的缓冲区被修改:在块加载时以及播放器修改世界时。所以,第一种情况很少见——在发生时使用异步复制,第二种情况很小很少见——如果您每帧记录一次命令缓冲区,您甚至可以将该副本偷偷放在那里
  • Nicol Bolas给出了更详细的答案


    顺便问一下,如果这是一个雷舰克隆,为什么要使用大量的索引?只需记录不同块的一些形状,然后使用实例存储这些块的世界位置和纹理ID。对绘制的不同形状使用“绘制”命令。在Vulkan中实现实例非常简单。您甚至可以使用计算着色器几乎立即生成世界数据

    “只是在运行中直接将顶点提交到顶点缓冲区。”这到底是什么意思?除非缓冲区位于可由CPU写入的内存中,否则无法从CPU向缓冲区“提交顶点”。如果它是CPU可写的。。。为什么要使用暂存缓冲区?我真的不知道将顶点“提交”到设备的正确单词。但我的意思是,当你记录命令缓冲区时,你把顶点缓冲区放到
    vkCmdBindVertexBuffers
    中,并在每一帧上运行??我使用索引,因为我认为我可以使用较小的索引来保存一些顶点缓冲区大小。四边形需要两个三角形:因此将有6个顶点,耗时6次