网站公告 | 泰斗网校全新上线了,可以和论坛用户登录同步,如果遇到登录问题联系管理员解决
查看: 2689|回复: 1
收起左侧

[已翻译] 没有人告诉你有关显卡落后1帧后的事情

[复制链接]

[已翻译] 没有人告诉你有关显卡落后1帧后的事情[复制链接]

是顾及啊 发表于 2018-3-8 13:51:12 [显示全部楼层] |只看大图 回帖奖励 |倒序浏览 |阅读模式 回复:  1 浏览:  2689
翻译:李庆璐(滴血红豆)  审校:翁僖骏(∈星际长途←)
我们的新游戏《王牌英雄》在各方面比《剑与勇士》的更复杂,所以为了能在所有平台上获得良好的帧率,我们需要认真地看待性能。现在在尝试优化的同时,我发现我完全误解了显卡的一个重要部分。
我曾经读过几本关于实时图形编程的书(包括整个OpenGL红皮书),但不知为什么,我从来没有读到相关的内容。所以当我发现时,我和其他几位有经验的图形学程序员交谈过,结果大多数人也不知道这一点。所以我想我的很多读者会觉得这很有趣。对于那些已经知道这一点的读者:为什么没人告诉我?!
那么我在说什么呢?我一直认为帧的时间安排是这样的:
DSC0000.gif
我一直认为一帧的工作空闲时间对于GPU来说是一个严重的问题。然而,事实证明这种方案是错误的!
一旦你开始调用显卡并渲染它,显卡就开始处理它们。然后,显卡通常调用它们并不会像接收一样快,所以当所有的帧被调用接收时,CPU会等显卡处理程序完成,然后再处理下一帧。
这个方案非常糟糕,因为它包含两个等待期:GPU和CPU在某一时刻都在等待,而且在这段等待期却什么也不做。这样浪费了性能。
我在《王牌英雄》上创建了一些定时器,我发现CPU花费了大量的时间等待GPU来调用SDL_GL_SwapBuffers之类的函数。我在我们引擎的所有版本中进行了测试,在每个平台上都发生过,索尼PS3游戏机,微软Xbox 360游戏机,电脑端。
我在一个单独的线程中实现了一个多线程的方案进行等待,这样当我们还在等待GPU完成前一帧的时候,下一个游戏帧就可以被处理了。(这实际上比它听起来复杂的多,但是我现在不考虑细节)。
发生了什么?什么都没发生!电脑端,索尼PS3游戏机,微软Xbox 360游戏机:没有显示任何帧率的改善!啊!所以我到处询问,找出我做错了什么,结果发现上面的方案完全是错误的。这根本不是它的工作原理。这才是这个方案的有效运作方式:
DSC0001.gif
这就是它的工作原理。GPU执行前一帧的渲染,所以它永远不会空闲。这种情况经常发生时,渲染每一帧的时间比CPU多。
所以当你调用D3DPresent函数或者sdl_gl_swapbuffer函数时,在那里花费的时间并不是等待当前帧,而是等待前一帧。对于我上面提到的等待问题,这实际上是一个非常简单和聪明的解决方案,只要GPU比CPU有更多的工作要做,它就永远不需要等待!
这就解释了为什么我的优化方案没有提供什么帮助:正如这张图片所展示的,GPU总是很忙,所以在这里使用多线程来提高CPU的帧率是完全没有用处的。
在这里提到的一个重要的事情是,我不是在讨论三重缓冲。三重缓冲是一个不同的主题,这个方案不管是否打开三重缓冲,都会发生(尽管为了更好地理解三重缓冲,你也需要考虑这个方案)。
注意,这种方案的一个副作用是引入了一些额外的输入延迟:用户输入(例如按下一个按钮跳转)在游戏状态更新中发生,在游戏状态更新和结果显示在屏幕上显示的时间之间的时间增加,由于这个方案,结果显示在屏幕上,但是,帧率也增加很多,所以这绝对是一个值得权衡的方案。
当然,如果你的游戏花在CPU上的时间超过了GPU,那么GPU仍然需要等待:

DSC0002.gif


这就是当渲染GPU所花费的时间比CPU少的时候发生的事情。GPU仍然处于闲置状态,但现在是因为没有更多的工作要做。
现在我的下一个问题是:它在所有平台上都是这样工作的吗?事实证明这是不同的。我到处询问,这就是我所学到的:
每个平台的情况各不相同,所以这里有一个展示了我所了解的每个平台的表格。
DSC0003.gif
在询问周围的情况时,我也了解到,在个人电脑上的某下情况下,驾驶者可能决定不等待。在《抽象赛车》的论坛上,有人说他在申请中输入了很长的时间。事实证明,这是因为GPU比1帧多很多,因为他的CPU几乎没有什么工作要做。所以在他的案例中,这个方案是这样的:
DSC0004.gif


在某些情况下,驾驶者不会等待,现在如果每帧GPU都比CPU长,CPU可以得到大量的时间,这就产生了巨大的输入延迟。
然而,我从来没有见过这种情况发生,所以我不确定什么时候会发生这个问题。我从一个用户那里听说,在Linux下运行时,《抽象赛车》有时会有严重的输入延迟。我自己还没有测试过这个问题,但我怀疑这是同样的问题。
然而,这个问题受到GPU的命令缓冲区大小的限制:当GPU落后太远时,整个缓冲区将会充满命令,所以CPU无法推进任何新命令,迫使CPU等待。
这可以用栅栏桌面(OpenGL和DirectX的高级功能)来解决。栅栏桌面允许你等待,直到GPU到达一个特定的点。您必须自己实现这一点,但它绝对可以保证GPU永远不会落后超过1帧。
总结一下,当你尝试优化你的游戏的时候,请牢记这个方案,并首先确保你的游戏是绑定的GPU还是CPU。在优化《王牌英雄》时,我的错误是我试图优化CPU,而坏的帧数是由GPU引起的。总是检查你的瓶颈!
我之前在博客上发表的关于《抽象赛车》的销售数据的文章,在网上引起了一些非常令人讨厌的评论。我曾试着写一篇非常积极的博文,说我对《抽象赛车》的成绩有多高兴,但Gamasutra网站和其他几个大型游戏网站简单概括为“《抽象赛车》的创造者对你想要的结果感到失望”。一些网站和评论者也对我如何解读销售数据做了一些恶意的误解。很多人认为我是一个抱怨者,有些人甚至对《抽象赛车》和我进行了一些严肃的讨论。这真的很令人讨厌,我做了一个有趣的游戏,特别是因为我对《抽象赛车》的制作非常满意,并且尝试写一个非常积极的博客文章。有趣的是,被误解会让人们在网上讨厌我……无论如何,我无法联系到所有的人,向他们解释我对《抽象赛车》的评论和收入有多高兴,所以我想我只能通过尝试做更酷的游戏来回答!
【版权声明】
原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。

+1
2683°C
1
  • snakebbf
过: 他们
因分享而快乐,学习以自强!
snakebbf 发表于 2018-3-8 19:14:32 显示全部楼层
谢谢分享
因分享而快乐,学习以自强!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

VR/AR版块|Unity3d|Unreal4|新手报道|小黑屋|站点地图|沪ICP备14023207号-9|【泰斗社区】-专注互联网游戏和应用的开发者平台 ( 浙ICP 备 13006852号-15 )|网站地图

© 2001-2013 Comsenz Inc.  Powered by Discuz! X3.4

1
QQ