【问题标题】:Rendering 1.2 GB of textures smoothly, how does a 1 GB GPU do this?平滑渲染 1.2 GB 的纹理,1 GB 的 GPU 是如何做到的?
【发布时间】:2011-11-10 14:16:56
【问题描述】:

我的目标是看看当使用比物理 GPU 内存容量更多的纹理数据时会发生什么。我的第一次尝试是加载多达 40 个 DDS 纹理,导致内存占用量远远高于 GPU 内存。但是,我的场景在 9500 GT 上仍能以 200+ fps 的速度渲染。

我的结论是:GPU/OpenGL 很智能,只将 mipmap 的某些部分保留在内存中。我认为这在标准配置上是不可能的,但无论如何。

第二次尝试:禁用 mip 映射,这样 GPU 将始终必须从高分辨率纹理中进行采样。再一次,我在内存中加载了大约 40 个 DDS 纹理。我使用 gDEBugger 验证了纹理内存使用情况:1.2 GB。尽管如此,我的场景还是以 200+ fps 的速度渲染。

我唯一注意到的是,当将相机移开然后再次将其对准场景中心时,会出现严重的延迟。好像只有这样它才会将纹理从主存储器传输到 GPU。 (我启用了一些基本的平截头体剔除)

我的问题:发生了什么事?这个 1 GB 的 GPU 如何以 200+ fps 的速度从 1.2 GB 的纹理数据中采样?

【问题讨论】:

  • 也许纹理的一部分在 GPU 内存中,一部分在 RAM 中?也许您在 CPU 和 GPU 之间共享内存?也许 PCI express 就是这么快?

标签: opengl textures gpu


【解决方案1】:

OpenGL 可以在两次绘制调用之间(不仅仅是在帧之间)将完整的纹理分页进出纹理内存。只有当前绘制调用所需的那些实际上需要驻留在图形内存中,其他的可以只驻留在系统 RAM 中。它可能只对您的纹理数据的一小部分进行此操作。它与任何缓存几乎相同 - 当您的 CPU 上只有 MB 缓存时,如何在 GB 数据上运行算法?

此外,PCI-E 总线具有非常高的吞吐量,因此您不会真正注意到驱动程序进行了分页。

如果您想验证这一点,glAreTexturesResident 可能有帮助也可能没有帮助,具体取决于驱动程序的实施情况。

【讨论】:

  • 听起来很有道理。然后一个有用的测试是加载更多的纹理,在 PCI-E 总线上放置一个不错的负载。我在更改视点时遇到的延迟,是否与 OpenGL 愚蠢和过早释放过多纹理内存有关?情况是:40个可见纹理(平滑),没有可见纹理(平滑),40个可见纹理(1个很长的帧,之后平滑)。
  • 这只是猜测。可能有缓存替换策略会导致这种情况,是的 - 例如,“未经训练的”缓存可能默认为类似于 LRU 的东西,如果您只是循环浏览数据,这是最糟糕的配置。如果您想得到答案,您必须咨询您的硬件/驱动程序制造商 - 不同的配置可能会给您带来完全不同的效果。
  • 另一方面,对于 1.2gb 的纹理数据,每帧至少需要重新加载 200mb。在 200FPS 时,这意味着 200x200 mb/s 将最大化每条现有的 PCI-E 总线。
  • 编辑:确实,我也刚刚意识到。无论如何,我会做更多的测试。感谢您的帮助。
  • 分页可能比单个页面更细粒度。我希望更新的驱动程序/卡可以做到这一点,尤其是 w.r.t. GPGPU 任务。在您缩小的情况下,某些页面可能永远不会被点击,因此它们不会被分页,实际上减少了 GPU 使用的内存量。
【解决方案2】:

即使您在测试中强制纹理抖动(每帧丢弃一些纹理并将其从系统内存上传到 GPU 内存),我不确定您是否如此,但现代 GPU 和 PCI-E 具有如此巨大的带宽一些颠簸确实会影响性能。其中一款 9500GT 型号的带宽为 25.6 GB/s,标准配置为 16 个 PCI-E 插槽(500 MB/s x 16 = 8 GB/s)。

至于延迟,我假设 GPU + CPU 在您不绘制可见纹理时会降低它们的功耗,而当您突然超载它们时,它们需要短暂的启动时间。在现实生活中的应用程序和游戏中,这种 0%-100% 的突然工作负载变化永远不会发生,所以我猜稍微滞后是完全可以理解和预料的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多