我应该在 GPU 上还是在 CPU 上计算矩阵?
Posted
技术标签:
【中文标题】我应该在 GPU 上还是在 CPU 上计算矩阵?【英文标题】:Should I calculate matrices on the GPU or on the CPU? 【发布时间】:2013-05-13 06:27:54 【问题描述】:我应该更喜欢在 CPU 还是 GPU 上计算矩阵?
假设我有以下矩阵 P * V * M
,我应该在 CPU 上计算它们以便我可以将最终矩阵发送到 GPU (GLSL) 还是应该将这三个矩阵分别发送到 GPU 以便 GLSL 可以计算最终矩阵?
我的意思是在这种情况下,GLSL 必须为每个顶点计算 MVP 矩阵,因此在 CPU 上预先计算它可能会更快。
但是假设GLSL只需要计算一次MVP矩阵,GPU计算最终矩阵会比CPU更快吗?
【问题讨论】:
你能举个例子,你只在GPU中执行一次这个计算吗? 1.最后优化。你确定你不只是拖延吗? :) 2. 如果您无法衡量性能并确定瓶颈,请不要考虑优化。 请注意,如果你是直接乘以一个向量,如projection * view * model * vertex
那么实际上没有matrix
乘法。只有matrix * vector
乘法,因为它是从右到左(projection * (view * (model * vertex)))
评估的。这对计算的负担要小得多。
【参考方案1】:
一般规则:如果您可以将其以 uniform 的形式传递给着色器,则 总是 在 CPU 上预先计算;没有例外。着色器端的计算仅对顶点和片段之间变化的值有意义。整批顶点中所有不变的东西都在 CPU 上得到最有效的处理。
GPU 并不是“可以做任何事情都更快”的神奇机器。在某些任务中,CPU 可以轻松胜过 GPU,即使对于非常大的数据集也是如此。所以一个非常简单的指导方针是:如果你可以将它移到 CPU 上,而不需要花费更多的 CPU 时间来进行计算,而不是 GPU 处理它的总开销,然后在 CPU 上进行。单个矩阵的计算属于这些任务。
【讨论】:
GPU 通常更快地解决“令人尴尬”的并行问题。 矩阵乘法不是并行的吗?每个元素都可以独立计算。 @Calmarius:是的,您可以并行化矩阵计算,事实上大多数 CPU 将使用它们的向量指令集并行化它。但是矩阵只需要精确地计算一次,并且对于使用该特定变换的模型的所有顶点保持相同。仅使 GPU 执行 4×4 矩阵乘法的开销就比在 CPU 上执行该计算需要更多的指令(和时间)。如果你想并行化 2k×2k 矩阵乘法,那么 GPU 会很好地并行化它。但是对于 4×4 矩阵,开销根本不值得。 这并不总是与 GPU 的速度和并行性有关。您需要记住,您的矩阵乘法发生在顶点着色器中的每个顶点上!如果你有一个包含数千个顶点的复杂网格,你猜怎么着?您将乘以 P x V x M 数千次,一遍又一遍地计算相同的精确 MVP 矩阵值。太浪费了。【参考方案2】:与 OpenGL 的大多数情况一样,这取决于。
在大多数情况下,在 CPU 上执行单个计算的速度比在 GPU 上要快。 GPU 的优势在于它可以并行执行大量计算。
另一方面,这也取决于您的瓶颈在哪里。如果您的 CPU 正在执行许多其他工作,但您的着色器还不是功耗最低的目标系统上的瓶颈,那么您可以通过将一些矩阵乘法移动到顶点着色器来轻松地看到一些性能提升。
通常,您应该避免片段着色器中的任何工作,这些工作也可以在顶点着色器或 CPU 上完成,但除此之外,这取决于具体情况。除非您遇到性能问题,否则请以最简单的方式进行操作,如果您遇到性能问题,请同时使用两种方式并分析性能以查看哪种方式效果更好。
【讨论】:
计算少量矩阵,尤其是 MVP 矩阵,绝不是 CPU 的瓶颈。 @datenwolf 不,它不是,但它也不是免费的。因此,如果程序对图形的要求不高,但其他部分对计算的要求很高,那么让 GPU 计算一些冗余 MVP 矩阵就可以了。正如我所说,这完全取决于情况。 让 GPU 进行计算的整个开销比简单的矩阵-矩阵计算需要更多的周期。您可以在现代 CPU 上使用 16 条指令进行 4×4·4×4 计算。这远远低于选择着色器程序、设置制服并通过发送要渲染的基元来让 GPU 的齿轮转动所需的内容。让 GPU 实际做某事的开销非常高,因此您尝试将尽可能大的作业批处理到 GPU。以上是关于我应该在 GPU 上还是在 CPU 上计算矩阵?的主要内容,如果未能解决你的问题,请参考以下文章