图形/仿真

高级 API 性能:命令缓冲区

这篇文章介绍了 NVIDIA GPU s 上命令缓冲区的最佳实践。要在应用程序中获得高且一致的帧速率,请参阅所有高级 API 性能提示.

命令缓冲区是从 CPU 发送要在 GPU 上执行的命令的主要机制。通过遵循本文列出的最佳实践,您可以通过最大化并行性、避免瓶颈和减少 GPU 上的空闲时间,在 CPU 和 GPU 上实现性能提升。

推荐

  • 接受您负责实现和控制 GPU / CPU 并行性的事实。
    • 向命令列表提交工作不会启动 GPU 上的任何工作。
    • ExecuteCommandList的调用最终在 GPU 上开始工作。
  • 在多个线程和内核上并行并均匀地将工作记录到多个命令列表中。
    • 录制命令是一项 CPU 密集型操作,没有驱动程序线程来拯救。
    • 命令列表不是自由线程,因此并行工作提交意味着提交多个命令列表。
  • 请注意,设置和重置命令列表会带来成本。
    • 为了高效地提交并行工作,您仍然需要合理数量的命令列表。
    • 围栏出于各种原因(多个命令队列、拾取查询结果等)强制拆分命令列表。
  • 尝试将目标设定为每帧 5-10 次ExecuteCommandList调用,并进行足够的 GPU 工作,以隐藏每次ExecuteCommandList调用的操作系统调度开销。
    • 在上一次ExecuteCommandList调用之后,操作系统需要 50-80 微秒来安排命令列表。如果调用中的命令列表执行速度快于此,则硬件队列中存在气泡。
    • 使用GPUView检查气泡。
  • 您可以将 3D 队列上的图形或计算工作与专用异步计算队列上的计算工作重叠。
    • 请记住,即使对于理论上可以与其他图形或计算任务并行运行的计算任务, GPU 上并行工作的实际调度细节也可能不会产生期望的结果。
  • 注意哪些异步计算和图形工作负载可以一起调度。使用围栏将正确的工作负载配对。
  • 使用ExecuteIndirect灵活性最大限度地将 CPU 工作卸载到 GPU 并减少 CPU – GPU 同步点。
    • 请使用ExecuteIndirect将场景消隐系统移植到 GPU 。
    • 使用ExecuteIndirect计数缓冲区来控制命令的数量,而不是发出最大数量的命令并单独预测未使用的命令。
    • NVIDIA 在ExecuteIndirectVulkan下为ExecuteIndirect提供附加功能

不推荐

  • 帧描述符堆中的 CBV / SRV / UAV 描述符或 2K 采样器不要超过 100 万个。
  • 不要阻止ExecuteCommandList呼叫。
    • ExecuteCommandList打电话可能会很贵。同时,可以在其他线程上记录新命令。
    • 每个命令队列都可以使用自己的线程来提交ExecuteCommandList
  • 不要只在几个命令列表中记录所有内容或大型场景部分。这限制了您充分使用所有 CPU 内核的能力。
    • 此外,构建几个大的命令列表意味着您可能会发现很难让 GPU 保持空闲状态。
  • 不要只在录制完所有内容后才提交。您可能会浪费使 GPU 与其他命令列表的录制并行工作的机会。
  • 不要期望大量的列表重用。
    • 在对象可见性等方面,每帧通常有许多更改。
    • 后处理可能是一个例外。
  • 不要经常混合使用绘图、分派和复制命令。
    • 尝试将所有绘制命令组合在一起,并将命令分派到一起,依此类推。
    • 在同一队列上频繁混合不同类型的工作可能会导致管道排水。
  • 不要创建太多线程或太多命令列表。
    • 太多的线程超额订阅 CPU 资源,而太多的命令列表可能会积累太多的开销。
 
 

 

Tags