代码之家  ›  专栏  ›  技术社区  ›  Xavier Ho

哪些opengl函数不是gpu加速的?

  •  26
  • Xavier Ho  · 技术社区  · 15 年前

    当我读到这个(从 OpenGL wiki ):

    gltranslate、glrotate、glscale

    这些硬件加速了吗?

    不,没有已知的GPU 执行这个。司机计算 CPU上的矩阵并将其上载到 GPU。

    所有其他矩阵运算都是 也可以在CPU上完成: glpushmatrix,glpopmatrix,格普矩阵, glloadidentity,glfrustum,格洛多。

    这就是为什么这些功能 在GL 3.0中被视为已弃用。 你应该有自己的数学图书馆, 建立自己的矩阵,上传 材质球的矩阵。

    非常, 非常 很长一段时间以来,我认为大多数opengl函数都使用gpu进行计算。我不确定这是否是一个常见的误解,但经过一段时间的思考,这是有意义的。旧的opengl函数(2.x及更旧版本)由于状态开关太多,实在不适合实际应用程序。

    这让我意识到,可能很多opengl函数根本不使用gpu。

    所以,问题是:

    哪个opengl函数调用不使用gpu?

    我相信知道上述问题的答案将帮助我成为一个更好的opengl程序员。请分享你的一些见解。

    编辑:

    我知道这个问题很容易导致优化水平。很好,但这不是这个问题的本意。

    如果有人知道某个流行实现(如Ashleysbrain建议的那样,NVIDIA/a t i,可能还依赖于操作系统)上的一组不使用GPU的GL函数,那就是我想要的!

    貌似合理的优化指南稍后提供。让我们关注这个主题的函数。

    编辑2:

    这个主题不是关于矩阵转换是如何工作的。有 other topics 为此。

    5 回复  |  直到 13 年前
        1
  •  36
  •   Bahbar    15 年前

    孩子,这是个大课题吗?

    首先,我将从显而易见的开始:由于您是从CPU调用函数(任何函数),它必须至少部分运行在CPU上。所以真正的问题是,有多少工作是在CPU上完成的,有多少是在GPU上完成的。

    其次,为了让gpu能够执行一些命令,cpu必须准备一个命令描述来传递。这里的最小集合是一个命令标记,描述要做什么,以及要执行的操作的数据。cpu如何触发gpu来执行命令也有些重要。由于大多数情况下,这是昂贵的,cpu不经常这样做,而是批处理命令缓冲区中的命令,并简单地发送整个缓冲区供gpu处理。

    所有这些都说明,把工作交给GPU并不是一项免费的活动。这一成本必须与仅仅在CPU上运行函数(不管我们在说什么)相比。

    退一步,你得问问自己为什么你需要一个GPU。事实是,一个纯cpu实现完成了这项工作(正如ashleysbrain所提到的)。GPU的强大功能来自其处理以下问题的设计:

    • 特殊任务(光栅化、混合、纹理过滤、拼接等)
    • 大量并行工作负载(deadmg在他的回答中指出了这一点),这时cpu更适合处理单线程工作。

    为了决定芯片中的内容,必须遵循这些指导原则。任何能从中受益的东西都应该在GPU上运行。任何其他东西都应该在CPU上。

    顺便说一下,这很有趣。德国劳埃德船级社的某些功能(主要是在折旧之前)并没有被清楚地描述出来。显示列表可能是此类功能的最佳示例。只要保留gl显示列表的语义,每个驱动程序都可以自由地从显示列表流推送到gpu(通常是以某种命令缓冲区的形式),以便以后执行 坚硬的 一般来说)。因此,有些实现只选择将显示列表中有限的调用子集推送到计算格式,并选择在cpu上简单地重放其余的命令流。

    选择是另一个不清楚在gpu上执行是否有价值的选择。

    最后,我不得不说,一般来说,api调用与cpu或gpu上的工作量之间没有什么相关性。状态设置api倾向于只修改驱动程序数据中的某个结构。它的效果只有在调用绘图或某些类似的绘图时才可见。

    很多gl api都是这样工作的。在那一点上,问 glEnable(GL_BLEND) 在CPU或GPU上执行是没有意义的。重要的是调用draw时是否在gpu上进行混合。所以,从这个意义上说, 大多数 德国劳埃德船级社的入口点根本没有加速。

    我也可以在数据传输上做一些扩展,但danvil提到了这一点。

    我将以“S/W路径”结束。从历史上看,无论硬件的特殊情况是什么,gl都必须按照规范工作。这意味着如果h/w没有处理特定的gl特性,那么它必须模拟它,或者在软件中完全实现它。有很多这样的例子,但其中一个打动了很多人是当glsl开始出现。

    由于没有实际的方法来估计glsl着色器的代码大小,因此决定gl应该采用任何着色器长度作为有效值。其含义相当明确:要么实现可以采用任意长度着色器的h/w(当时不太现实),要么实现s/w着色器仿真(或者,正如一些供应商选择的那样,根本无法兼容)。因此,如果在片段着色器上触发此条件,则可能是 整体 你的GL最终在CPU上被执行,即使你有一个空闲的GPU,至少在那次抽签中。

        2
  •  7
  •   Danvil    15 年前

    问题也许应该是“哪些函数占用了出乎意料的大量CPU时间?”

    为投影和视图保留一个矩阵堆栈并不是gpu能够比cpu更好地处理的事情(相反…)。另一个例子是着色器编译。为什么要在GPU上运行?有一个解析器,编译器,…,这只是普通的CPU程序,比如C++编译器。

    例如,潜在的“危险”函数调用 glReadPixels ,因为数据可以通过有限的总线从主机(=CPU)内存复制到设备(=GPU)内存。在这一类中还有一些函数 glTexImage_D glBufferData .

    所以一般来说,如果你想知道opengl调用占用了多少cpu时间,试着理解它的功能。注意所有的功能,它们将数据从主机复制到设备,然后再复制回来!

        3
  •  7
  •   Puppy    15 年前

    通常,如果某个操作是针对某个对象的,它将在gpu上发生。一个例子是实际的转换-这是每个顶点一次。另一方面,如果每次大型操作只发生一次,那么它将在CPU上——例如创建转换矩阵,每次对象的状态更改或每帧一次。

    这只是一个一般性的答案,一些功能将以另一种方式出现——而且依赖于实现。然而,一般来说,这对程序员来说并不重要。只要你允许gpu有足够的时间在你不玩sim或其他游戏的时候工作,或者有一个可靠的线程模型,你就不需要担心那么多。

    @向gpu发送数据:据我所知(仅使用direct3d),这都是在shader中完成的,这就是shader的用途。

        4
  •  4
  •   Axel Gneiting    15 年前

    gltranslate、glrotate和glscale更改当前活动的变换矩阵。这当然是一个CPU操作。模型视图和投影矩阵只描述了当发出渲染命令时,gpu应该如何变换顶点。

    因此,通过调用gltranslate,还没有翻译任何内容。在渲染当前投影和模型视图矩阵之前,将其相乘(MVP=投影*模型视图),然后将此单个矩阵复制到GPU,然后GPU对每个顶点执行矩阵*顶点相乘(“T&L”)。所以顶点的平移/缩放/投影 由GPU完成。

    另外,如果不在某个内部循环中使用这些函数,您也不必担心性能问题。gltranslate结果 添加物。glscale和glrotate要复杂一些。

    我的建议是你应该多学点线性代数。这对于使用3d api是必不可少的。

        5
  •  2
  •   AshleysBrain    15 年前

    有opengl的软件呈现实现,所以有可能 opengl函数在gpu上运行。还有一些硬件不支持硬件中的某些渲染状态,因此如果设置了某个状态,请切换到软件渲染,然后再次,GPU上不会运行任何东西(即使有一个GPU)。所以我不认为‘gpu加速函数’和‘非gpu加速函数’有什么明显的区别。

    为了安全起见,尽量保持简单。具有顶点和基本特性(如z缓冲)的直接渲染是 最可能 为了加速硬件,所以如果你能在最小状态变化的情况下坚持这一点,你将很可能保持硬件加速。这也是最大限度地提高硬件加速渲染性能的方法-图形卡喜欢保持在一种状态,只需处理一堆顶点。