图形/仿真

高级 API 性能:障碍

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

为了在我们的硬件上获得最佳性能,以下是在 DX12 或 Vulkan 中使用屏障时应该做和不应该做的事情。这是从DX12 注意事项更新的。

推荐

  • 尽量减少使用障碍物和围栏。任何障碍物或栅栏都会限制平行度。我已经看到冗余屏障和相关的等待空闲操作是 DX11 到 DX12 端口的主要性能问题。
    • DX11 驱动程序在减少障碍方面做得很好。在 DX12 下,您必须这样做。
  • 确保始终使用最小的资源使用标志集。冗余标志可能会触发冗余刷新和暂停,并不必要地降低游戏速度。同样,我看到冗余或过于保守的屏障标志及其相关的等待空闲操作是 DX11 到 DX12 端口的主要性能问题。
    • 不要使用D3D12_RESOURCE_USAGE_GENERIC_READ,除非您确实需要在这些标志组合中设置的每个标志。
  • ID3D12CommandList::ResourceBarrier中指定最小目标集。添加虚假依赖项会增加冗余。
  • 在一次呼叫ID3D12CommandList::ResourceBarrier中分组障碍。这样,可以选择最坏的情况,而不是依次通过所有障碍。
  • 使用单个空到空的别名资源屏障,而不是多个(例如, 200 +资源到空的屏障)。在驱动程序中可能是相等的,处理所有这些数据可能会浪费 CPU 个周期。
  • 如有可能,使用分离式屏障。
    • 使用D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLYD3D12_RESOURCE_BARRIER_FLAG_END_ONLY标志。这有助于驱动程序优化过渡工作负载的调度。
  • 使用围栏向ExecuteCommandLists发送事件信号或跨越呼叫。

不推荐

  • 不要插入多余的屏障:
    • D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCED3D12_RESOURCE_STATE_RENDER_TARGET再到D3D12_RESOURCE_STATE_RENDER_TARGET的转换是多余的,其间没有任何draw调用。
    • 避免阅读障碍。为所有后续读取获取处于正确状态的资源。
  • 没有充分的理由不要使用D3D12_RESOURCE_USAGE_GENERIC_READ
    • 对于从写入状态到读取状态的转换,请确保转换目标包含下一次写入转换之前所需的所有读取状态。这是通过组合读取状态标志从 API 完成的,在后续的ResourceBarrier调用中,最好是从读取转换为读取。
  • 除非绝对需要,否则不要将D3D12_RESOURCE_STATE_COMMON状态用于非初始状态。D3D12_RESOURCE_STATE_COMMON是可升级到读和写状态的状态,因此它使驱动程序选择最差的同步度量。
 

Tags