与保留模式 GUI 相比,使用立即模式 GUI 对性能有何影响?

pul*_*ser 156 c++ performance user-interface desktop-application immediate-mode

我目前正在开发一个标准的 Windows 桌面应用程序(标准意味着没有花哨的东西:只有按钮、文本、滑块等),并且在研究了一些 GUI 框架并被排斥后决定自己编写一个 GUI 框架他们都。由于这是一个业余项目,我也愿意尝试,并决定使 GUI 立即模式,而不是保留模式,因为我非常喜欢它简化代码的方式。不过,这里有一个问题:

当将即时模式 GUI 用于典型桌面应用程序时,与保留模式 GUI 相比,使用即时模式 GUI 对性能有何影响?

我总是听说 IMGUI 的性能更差,因为它必须重绘每一帧(或者,如果它以某种方式缓存,它仍然必须每帧都执行逻辑)。但我们在这里谈论的还有多少?我是不是消耗了两倍的 CPU 时间?更多的?如果我假设运行 20 个 IMGUI 程序,它会最大限度地使用 CPU(假设我已经对其进行了优化)?我只是想知道大概情况以及权衡在非游戏环境中是否仍然可行,在这种环境中无需重新绘制每一帧。

还有一个我不明白的关于延迟的含义。在章讨论IMGUI工作正在进行书约翰内斯Norneby,解释如下:

框架剪切

在实时应用程序的上下文中需要注意的 IMGUI 的一个方面(每秒不断渲染新帧多次)是用户交互将始终响应在前一帧上绘制的内容。这是因为用户界面必须至少绘制一次,以便用户知道那里有要与之交互的小部件。大多数情况下,如果帧速率足够高,这不会导致任何问题,但这是需要注意的。

这在保留模式 GUI 中有何不同?这是否意味着我在保留模式的 GUI 上多了一个输入延迟帧?

pul*_*ser 229

由于似乎仍然对这个问题有些兴趣(从观点来看),我想我不妨发布一个更新。

我最终实现了一个即时模式 GUI 作为我的硕士论文,并且有一些关于性能的数字。要点是:

立即模式在很多情况下更好(更快),而仅在某些情况下更差(更慢)。总体而言,这是创建快速响应且不会耗尽电池电量的 GUI 的完全可行的方法。

我用大约 50% 的 UI 元素创建了一个 Spotify 克隆,渲染单个帧在微秒范围内。事实上,应用程序始终使用少于 400 ?s 的单个帧。在 60 Hz 监视器上启用 V-Sync 时,这相当于单核上大约 3% 的 CPU 负载(每 16 毫秒 400 ?s)。此外,这 400 ?s 中的相当一部分是由不会增加更多 UI 元素的负载的恒定因素引起的(例如,接收输入或设置不随 UI 复杂性扩展的 GPU 状态)。

我的完美主义者仍然不喜欢这样一个事实,即什么都不做的 GUI 会消耗周期,但好处是巨大的:当 GUI 被大量交互时,或者当窗口被调整大小时,它仍然达到 400 ?s!这使许多现有的保留模式 GUI 脱颖而出。尝试调整 Spotify、Windows 资源管理器、Visual Studio 或基本上任何其他桌面应用程序的大小,看看它是如何反应的,以了解我的意思。我的猜测是在调整大小时,Spotify 在我的 PC 上会下降到大约 2 fps。

更改用户界面基本上是免费的。如果在一帧中显示一百个按钮,然后在下一帧中将它们全部替换为文本框,则性能仍然没有区别。保留模式 GUI 在这种情况下往往会遇到困难。

还有三个想法:

  • 大部分时间都花在了文本渲染上,其余时间几乎无关紧要。如果你想大量优化,这将是重点。但即使很少优化,它也可以做得不错。

  • 我怀疑性能上的巨大差异只能——甚至根本不能——用保留模式和直接模式之间的差异来解释。例如,Spotify 使用 Web 堆栈作为 UI;那肯定会很慢。

    我想,WPF、Win32 之类的东西之所以慢,是因为它们可以侥幸逃脱,或者因为它们针对与我们现在使用的硬件完全不同的硬件进行了优化。当然,他们也做得更多,但远不足以证明差异是合理的。

  • 我相信您可以制作一个比我的即时模式 GUI 快得多的保留模式 GUI。老实说,总的来说,它几乎没有什么动力,这有点令人伤心;我喜欢有效率的东西。

对我来说,关键要点是:IMGUI 很好,你可以让它很快。

更新

既然有人问了,我决定发布我的论文。

请注意,您将看到一些不打算公开发布的东西,并且没有通过我个人对公开发布的软件的最低质量期望(这就是我没有首先发布它的原因)。因此,请仅将其用于教育目的,而不是用于构建实际软件。我也不会支持。

下载内容包括论文本身(德语!)、一些预构建的 Windows 可执行文件和源代码(C++):

https://1drv.ms/u/s!AsdZfH5hzKtp9zy1YZtHgeSMApOp?e=FbxLUs

玩得开心!

  • 我很高兴您没有采纳评论中的建议,即您不应该自己编写:) 干得好。 (31认同)
  • 恭喜您进入黑客新闻:https://news.ycombinator.com/item?id=25624044 请绝对_do_考虑分享您的代码,即使它是“学术”质量的。只有好的结果才会产生。此外,这正是 CRAPL 许可证的用途:p (22认同)
  • 请在公开发布时分享您的论文:) (14认同)
  • 三年来的答案。做得好!第一个问题:您是如何比较这两种范式的?第二个问题:您有项目实施细节的链接吗?谢谢你! (8认同)
  • 我刚刚意识到我并没有真正回答你的第一个问题:首先,我从理论角度对它们进行了比较:在 ImGUI 中,你描述你希望 UI 具有的状态,在保留模式下,你指定状态之间的转换。我不会深入探讨它,但它可以归结为:保留模式可以具有 n² 复杂性,而立即模式几乎保持线性。然后,我构建了一个应用程序来将性能与其他保留模式应用程序进行比较。这不是很科学,所以除了“它有效并且大多更好”(对于我的用例)之外,没有真正的知识。 (7认同)
  • 我遇到了 Casey Muratori 的 Handmade Hero 和 DearImgui Library 的范式。在我“只想为我的程序提供一个 GUI”并了解到 GUI 框架对于最终用户程序的前景是多么糟糕之后,我决定在我的硕士论文中探讨这个主题。这一切都太可怕了。所以我采取了“这不可能那么难”的方法。我还没有在任何地方上传我的实现,主要是因为它具有真正的学术质量(相当蹩脚),而且我不想用它来诅咒其他人。如果您想查看 ImGUI 实现,请查看 Github 上的 DearImgui 或 Nuklear。 (3认同)
  • @TasosPapastylianou 所以这就是你们所有人的结局:DI 现在会考虑发布它,但 CRAPL 许可证太罗嗦了。也许我会发明自己的许可证:“这是狗屎代码,请不要使用它。” 应该做。 (3认同)
  • @pulp_user 干得好!您是否尝试过不渲染每一帧,而仅在存在一些用户输入或内部状态更改且具有可见效果时才渲染?也许在某些情况下,如果您能够可靠地过滤这些内容,那么大多数时候您甚至可以节省 3% 的 CPU。 (2认同)
  • 很棒的工作。我想部分原因是你无法摆脱即时模式 GUI 中缓慢的情况。保留模式可能会隐藏各种慢速路径。这让我想知道是否每个保留模式 GUI 都应该有一个立即模式以确保其保持高性能。 (2认同)
  • 天哪,这是我很长一段时间以来读到的最好的答案!干得好:) (2认同)
  • @TomasAndrle 不,因为它对我的用例没有多大帮助。由于您只知道应用程序重建整个 UI 后内部状态没有改变,因此此时您已经花费了总 CPU 时间的 80%。考虑到时间限制,将逻辑变得极其复杂(并做出一些设计决策)以减少 20% 左右,感觉没有什么用处。说实话,这种优化实际上可能是净损失,因为缓存逻辑可能比总渲染花费更多的时间。但这很难说。我会从改进文本渲染中获得更多。 (2认同)
  • @TasosPapastylianou 我不喜欢啤酒,所以这也不是我的许可证:DI 会找到一些东西! (2认同)
  • @Louise不幸的是,我的论文是德语的,所以它对绝大多数人来说没有用。不过,我正在考虑用示例翻译这一章,这样我就可以将其与源代码捆绑在一起,人们至少可以通过示例来弄清楚。我不相信机器翻译的 pdf 具有很好的可读性。 (2认同)
  • @brightprogrammer我使用DirectX11。如果你优化得足够多,我认为保留模式仍然领先,只是当前许多框架的性能很糟糕,并且在交互时电池使用率更高。在这方面,我真的不能说“这个更好”,只是两者都是可行的方法。可定制和灵活取决于实施细节。您可以制作非常可定制的保留模式和不可定制的即时模式指南,反之亦然。这实际上更多的是关于如何设计 api 的问题。 (2认同)