高级 API 性能:描述符

这篇文章最初发表在 NVIDIA 技术博客上。

通过使用描述符类型,您可以将资源绑定到着色器,并指定如何访问这些资源。这可在 CPU 和 GPU 之间实现高效通信,并使着色器能够在渲染期间访问必要的数据。

推荐

  • 首选"无绑定"设计。
    • 使用无界数组描述符,指向包含帧所需的所有已知纹理、缓冲区和加速结构的大型描述符表或集合。
    • 预先上传尽可能多的数据(纹理、每绘制常量和每帧常量),并通过这些描述符数组进行访问。
    • 这种设计还可以更轻松地实现光线追踪,即允许访问每个着色器中的每个纹理和缓冲区。
    • 将描述符缓存在 GPU 可见的描述符堆 (DirectX 12) 或具有已知偏移量的集合 (Vulkan) 上。这降低了 CPU 开销,几乎消除了复制描述符的需求。
    • 使用堆的多个副本以优雅方式处理描述符更改,例如流式传输纹理和缓冲区。但不要超过 1M 和 2K 的限制。有关更多信息,请参阅本博文后面的 不推荐 小节。
  • 使用根 (DirectX 12) 或推送 (Vulkan) 常量。它们是每次绘制传输不同常量的最快方法。
  • 在 Pascal 上:对于常量数据,首选 CBV 而非 SRV.
    • 一般来说,SRV 缓冲区的速度要比 <=Pascal 上的 CBV 缓冲区慢。
    • Volta 及更高版本的性能相当。
    • 更好的方法是尝试使用根常量。
      • 即使对于不经常更改的数据(例如,材质数据、通道数据和每帧数据),它们也可以更快。

DirectX 12

  • 您可以随意更大限度地使用完整的 64 DWORD根签名中可用的数据类型。
  • GPU 和 CPU 上的性能排名:
    1. 根常量是最快的,没有间接,并且可以直接索引。
    2. 根 CBV/SRV/UAV 是第二快,具有单向和无边界检查。
    3. 描述符表速度最慢,需要检查两个间接和边界。
  • 例如 HLSL SM 6.6,使用动态资源绑定。
  • 切换根签名是一项快速操作。
    • 使用多个根签名来提高绑定效率可能是一种有效的策略。
    • 这对于非无绑定设计尤其如此。
    • 在不必要地重新绑定大量数据时,它可能效率低下。切换根签名会导致现有绑定丢失。
  • 在某些情况下,使用 Root Signature 1.1 可以获得略高的性能。
    • 特别是,使用 DATA_STATIC_SET_AT_EXECUTE 尽可能让驱动程序提前内联一些数据。
    • 这不是高优先级;仅在方便时使用。

Vulkan

  • 尽量减少管道布局中描述符集的数量。
  • 使用动态统一缓冲区和存储缓冲区进行每次绘制调用更改。
  • 首选使用组合图像和采样器描述符。
  • Vulkan 1.2 支持将存储缓冲区的设备地址作为 64 位值传递给着色器。这可实现 DirectX 或 HLSL 中无法使用的类似指针的工作流(例如投射)。GLSL 通过 GL_EXT_buffer_reference (2) 并使用 SPV_EXT_physical_storage_buffer。尝试优化 buffer_reference_align 因为硬件可以相应地利用更广泛的内存加载操作。

不推荐

  • 整个应用程序(GPU 可见)的活动描述符和采样器总数不得超过 100 万个。
    • 否则,在切换描述符堆 (DirectX 12) 时,整个 GPU 的工作流可能会停滞。
    • 每当超过限制时,它都会降低命令列表的异步执行效率。
    • 在 Vulkan 上,驱动程序会自动执行描述符的重复数据删除。前面提到的限制仅计入独特的变体。
      • 通常情况下,请尽量低于VkPhysicalDeviceLimits.
  • 尽可能避免使用类型化的 UAV 负载或存储。

DirectX 12

  • 防止在帧期间过度创建或复制描述符。
    • 永久性地保留描述符,而不是在每一帧中重新分配或复制它们。
    • 在描述符表中使用根 CBV 而非 CBV.
      • 无需调用CreateConstantBufferView具有根 CBV.
    • 仔细选择较小的描述符表也可以改善这种情况。
  • 尽可能将重复的描述符减少为相同的资源。
    • 示例:不应在描述符 0、10、20、30、40、50 等中引用纹理 0.
    • 相反,请尝试更改描述符表的布局,以便能够多次重用相同的描述符。

Vulkan

  • 不要在单个描述符集中存在过于稀疏的绑定偏移。
    • 尽可能紧密地打包。
    • 未使用的绑定索引会浪费内存并降低缓存效率。

阅读原文

相关推荐
扫地的小何尚9 天前
NVIDIA RTX 系统上使用 llama.cpp 加速 LLM
人工智能·aigc·llama·gpu·nvidia·cuda·英伟达
布鲁格若门9 天前
AMD CPU下pytorch 多GPU运行卡死和死锁解决
人工智能·pytorch·python·nvidia
centurysee11 天前
【一文搞懂】GPU硬件拓扑与传输速度
gpu·nvidia
算家云17 天前
moffee模型部署教程
人工智能·python·github·markdown·nvidia·ppt·幻灯片制作
坐望云起1 个月前
Ubuntu20.04 更新Nvidia驱动 + 安装CUDA12.1 + cudnn8.9.7
linux·ubuntu·nvidia·cuda·onnx·1024程序员节
RZer1 个月前
NVIDIA 发布适用于网络安全的 NIM Blueprint
安全·web安全·nvidia
LifeBackwards1 个月前
Ubuntu安装nvidia显卡驱动
ubuntu·显卡·nvidia
great-wind1 个月前
麒麟系统离线安装英伟达驱动
nvidia
utmhikari1 个月前
【DIY小记】新手小白超频i9-12900kf和3070ti经验分享
cpu·显卡·nvidia·超频·微星
学森杰登1 个月前
大模型生成PPT大纲优化方案:基于 nVidia NIM 平台的递归结构化生成
人工智能·python·自然语言处理·chatgpt·powerpoint·nvidia