为什么从 GPU 向 CPU 发送数据存在瓶颈,而从 CPU 向 GPU 发送数据则没有那么瓶颈?

为什么从 GPU 向 CPU 发送数据存在瓶颈,而从 CPU 向 GPU 发送数据则没有那么瓶颈?

我最近在学习编写着色器。我经常看到人们向 GPU 发送数兆字节的纹理或粒子数据,但有时却没有任何实际问题。

但是当我读到将数据从 GPU 发送回 CPU 时 — — 最好避免这样做,因为它很慢,尤其是在数据量很大的情况下。

我在尝试实现傅立叶变换 (FFT) 算法时遇到了这个问题,然后通过纹理在 CPU 上每帧采样结果……将数据发送回 CPU 的速度太慢了。这是为游戏设计的,因此性能很重要。

为什么硬件制造商不设计他们的硬件来解决这个问题?

答案1

为什么硬件制造商不设计他们的硬件来解决这个问题?

首先,请允许我先说明一下,我不是 PCI Express 或 GPU <-> CPU 通信低级实现方面的专家。我相信该级别的一些细节可能会使性能偏向于 CPU 到 GPU。

但在大多数情况下,我认为瓶颈是在软件/API 级别。GPU 在 GPU -> CPU 方向上具有足够的性能。

OpenGL 和 DirectX 等图形 API 旨在实现图形管线在 GPU 上。最简单的形式是,管道是一个单程数据从 CPU 流向 GPU,再流向显示器。这些 API 旨在尽可能优化该管道,以便游戏和其他图形应用程序能够实现高帧率。

尽管如此,仍然有方法从 GPU 检索数据,例如在 OpenGL 中:

  • 转换反馈
    可用于将顶点着色器的输出捕获到缓冲区中。

  • 像素缓冲区对象
    可用于在 CPU 和 GPU 内存之间传输渲染目标或纹理。

使用这些方法就像在管道的某个地方放置一个交通信号灯。这是因为将数据传输回 CPU 内存意味着必须锁定数据。但是渲染管道可能需要该内存来处理下一帧,因此每帧将共享数据复制回 CPU 将迫使 GPU 在复制数据和处理管道之间交替进行。

为了避免该问题,可以进行的最大优化是在每帧之间切换两个或多个缓冲区,以便 GPU 下载不必阻塞管道。


我还应该提到,CUDA 和 OpenCL 等 GPU 计算 API 旨在让开发人员更好地控制着色器的使用方式;它们不会强迫您在任何预制管道中使用它们。您可以在计算着色器中生成波浪几何图形,将其复制回 RAM 进行物理处理,然后将其传回图形 API 进行渲染。您还可以让计算 API 与图形 API 进行互操作,以便顶点数据可以在 GPU 内存本身中移交。

相关内容