我应该在GPU还是CPU上计算矩阵?

56

我应该在 CPU 或 GPU 上计算矩阵吗?

假设我有以下矩阵P * V * M,我应该在 CPU 上计算它们,以便将最终矩阵发送到 GPU(GLSL),还是应该将这三个矩阵分别发送到 GPU,以便 GLSL 可以计算最终矩阵?

我的意思是,在这种情况下,GLSL 必须为每个顶点计算 MVP 矩阵,因此在 CPU 上预先计算可能更快。

但是,假设 GLSL 只需要计算一次 MVP 矩阵,那么 GPU 是否比 CPU 更快地计算出最终矩阵?


1
你能给一个例子,说明你只在 GPU 上执行这个计算一次吗? - Amadeus
3
  1. 最后再优化。你确定你不是在拖延吗? :)
  2. 如果您无法测量性能并确定瓶颈,请不要考虑优化。
- Andreas Haferburg
只是一个提示,如果您直接对向量进行乘法运算,例如 projection * view * model * vertex,那么实际上没有矩阵乘法。只有从右到左进行的 矩阵*向量 乘法,因为它从右到左计算 (projection * (view * (model * vertex)))。这在计算上要轻松得多。 - Justin Meiners
2个回答

85

通用规则:如果可以将计算结果以 uniform(一致变量) 的形式传递给着色器,则始终在 CPU 上预先计算,没有例外。在顶点和片段之间发生变化的值才有意义会在着色器上进行计算。整个顶点批次中始终保持不变的所有内容最好在 CPU 上处理,效率最高。

GPU 不是能够快速处理所有任务的神器。对于某些任务,即使对于非常大的数据集,CPU 也能够轻松地胜过 GPU。因此,一个非常简单的指南是:如果可以将其移动到 CPU 上,在计算所需的 CPU 时间不超过 GPU 处理总开销的情况下,请在 CPU 上进行计算。单个矩阵的计算就属于这些任务之一。


11
通常情况下,GPU对于那些“尴尬地”具有并行性的问题处理速度更快。 - fluffels
8
翻译:矩阵乘法不是可以并行计算吗?每个元素都可以独立地进行计算。 - Calmarius
7
@Calmarius:是的,你可以并行计算矩阵,实际上大多数CPU都会使用其向量指令集并行化计算。但是,这些矩阵只需要计算一次,并且对于使用该特定转换的模型的所有顶点保持不变。仅仅为了使GPU执行一个4×4矩阵乘法的开销就需要更多的指令(和时间)比在CPU上进行计算。如果你想并行计算比如2k×2k的矩阵乘法,那么GPU将很好地并行化它。但对于一个4×4的矩阵,这种额外的开销根本不值得。 - datenwolf
9
重点不总是在于GPU的速度和并行性。你需要记住,在顶点着色器中的每个顶点上都会进行矩阵乘法计算!如果你有一个包含数千个顶点的复杂网格,你会进行P x V x M数千次的乘法运算,一遍又一遍地计算相同的MVP矩阵数值。这是浪费的。 - mchiasson

14

与OpenGL的大多数情况一样,这取决于具体情况。

在大多数情况下,单个计算在CPU上比GPU上更快。 GPU的优点在于它可以同时执行大量计算。

另一方面,这也取决于您的瓶颈在哪里。如果您的CPU正在进行大量其他工作,但是您的着色器在最低功率目标系统上尚未成为瓶颈,则通过将某些矩阵乘法移动到顶点着色器中可能很容易地看到一些性能提升。

通常,您应避免在片段着色器中执行任何可以在顶点着色器或CPU上执行的工作,但除此之外,这取决于具体情况。除非您遇到性能问题,否则只需以最简单的方式进行操作;如果您遇到性能问题,请使用两种方法并分析性能以查看哪种方法效果更好。


5
计算一些矩阵,尤其是MVP矩阵,从未成为CPU的瓶颈。 - datenwolf
7
@datenwolf并不是这样,但它也不是免费的。所以,如果程序不需要大量图形计算,但有其他需要进行计算的部分,让GPU计算一些冗余的MVP矩阵可能会很好。正如我所说,这完全取决于情况。 - bcrist
9
让GPU计算任何东西所需的开销比简单的矩阵乘法要高得多。在现代CPU上,你可以用16条指令完成4×4·4×4的计算。这远远少于选择着色器程序、设置uniform并通过发送原始数据来启动GPU的开销。让GPU实际执行操作的开销相当高,因此您应尽可能将作业批量处理以便输入到GPU中。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接