图拉丁吧 关注:7,332,719贴子:125,622,795

小科普 | 游戏中的“垂直同步”与“三重缓冲”究竟是个啥?

只看楼主收藏回复

大家好,我是极客湾的飘哥,今天来和大家探讨一下“垂直同步”与“三重缓冲”的功能与作用。
1.它到底是干嘛用的?
2.它有什么缺点吗?
3.和它搭档的“三重缓冲”又是个啥?
以及最重要的一点:我在游戏中到底该不该开启它?
(本文中的部分内容参考自外媒 Anandtech 的技术文章,我们将在文末提供其链接)
另外,本文阅读起来有难度,如果你是抱着太长不看的心态阅读,建议直接看最后的结论 。


IP属地:上海1楼2017-03-28 13:25回复
    ▌垂直同步是干嘛的?
    要想解答这个问题,首先得来说说“垂直同步”所解决的问题——画面撕裂。当我们在玩游戏的时候,有没有遇到下图这种情况呢:

    一帧画面被分割开了,这种情况便是“画面撕裂”。
    不过你可能会说,我用的可是高端显卡呀,为什么还会出现这种问题呢?
    你还别说,越是高端的显卡,跑到的帧数越高,还就越容易出现这种问题。


    IP属地:上海2楼2017-03-28 13:25
    收起回复
      这里就要说说说画面撕裂产生的原因了。为了方便各位理解,我们先来简单说说显卡与显示器之间是如何工作的:

      可以看到,显存中的“帧缓冲区”(Framebuffer)是图像传输的一个关键区域,显卡所生成的一帧画面会先被写入帧缓冲区。而一台 60Hz 的显示器每秒能够显示 60 幅画面,也就是说每 1/60 秒(当显示器刷新完一幅画面时)会给显卡发送一次“垂直同步信号“,向帧缓冲区索取一次画面数据,然后显示出来。


      IP属地:上海3楼2017-03-28 13:27
      回复
        不过光有一个帧缓冲区会产生一个问题,这一个缓冲区会不断地写入新的画面并发送给显示器,这样一来“写入的全过程”就会被展现在屏幕上了,这就会导致画面闪烁等问题。因此,现代的图形工作流程中使用的多是双重缓冲:

        双重缓冲有一前一后两个缓冲区,显卡只会将绘制完的图像写入后缓冲区,与此同时只有前缓冲区中的图像会被发送给显示器。
        当后缓冲区中的“新鲜”图像写入完成后,注意啦,程序不会将后缓冲区的画面传输到前缓冲区,而是会进行缓冲区的交换(Swap)——将前缓冲区和后缓冲区的名字对调,即前缓冲区成了后缓冲区,后缓冲区成了前缓冲区。这样以后,刚刚绘制在后缓冲区的图像就能顺利地传给显示器了。经过这么一折腾,程序就可以在往后缓冲区写入图像的同时,不影响显卡将前缓冲区中的画面传给显示器,然后进行下一次“缓冲区交换”。


        IP属地:上海4楼2017-03-28 13:29
        回复
          但是双重缓冲有个问题,两个缓冲区随时都可能发生交换,所以就会出现这种情况:前缓冲区中的画面才刚传输了一半给显示器,两个缓冲区就发生交换了,后面传输的都是原来后缓冲区中的画面(即下一帧画面)。于是,显示器上的一幅画面成了前后两帧的结合,这就是画面撕裂。这种问题在高帧率情况下尤为显著,因为帧率越高,前后缓冲区的交换就越为频繁,发生这种事件(画面没输出完就交换了)的概率自然也就更高。


          IP属地:上海5楼2017-03-28 13:29
          回复
            前排?等删?


            IP属地:江苏来自Android客户端6楼2017-03-28 13:30
            回复
              即刻弯


              IP属地:广东来自Android客户端7楼2017-03-28 13:30
              回复
                - 哇,原来画面撕裂是这么来的啊!那有没有什么办法能解决它呢?
                - 当然有了,那就是“垂直同步”选项。
                (PS:“垂直同步”是一种简写,完整的称呼应是“等待垂直同步信号”)
                开启垂直同步,就相当于在帧缓冲区里架设了红绿灯。当显示器尚未完成一帧画面的刷新时,红灯亮起,两个缓冲区不允许交换;当显示器刷新完一帧画面时,绿灯亮起,此时缓冲区可以进行交换了。这样以后就杜绝了“在进行数据传输的过程中交换缓冲区“的可能,自然也就解决了画面撕裂的问题。

                不过为啥这个功能要叫“垂直同步”呢?这是因为在 CRT 大屁股显示器的年代,显示器的刷新是逐行或隔行刷新的,电子枪一行一行地打下去,打完每一行就称这一行完成了“水平同步”,打到最后一行的最后一个像素点就完成了一帧画面的显示,然后显示器会给显卡发送“垂直同步信号”,表明垂直向的像素点也完成了同步,即这一帧刷新完成了。


                IP属地:上海8楼2017-03-28 13:30
                回复
                  - 哇,垂直同步这么好,那我现在就去游戏里打开它,如何?
                  - 别急,“垂直同步”虽然能彻底杜绝画面撕裂,但是它的副作用同样很明显——操作延迟。
                  在帧率比显示器刷新率高很多的情况下,为了将显示器的刷新时间和显卡向缓冲区写入画面的时间保持同步,必然就需要人为地增加延迟,来延后“过快生成的画面“向显示器的输出。因此在竞技游戏中,开启垂直同步后的手感会大打折扣。
                  这里用一个实例来作说明:

                  这是未开启垂直同步时,传统双重缓冲下的图像,由于 300fps 的高帧率,每两个“垂直同步信号“之间会生成高达 5 幅画面,这就导致了严重的画面撕裂。

                  这是开启了垂直同步后的图像,可以看得出画面撕裂的问题确实得到了解决,但为了将帧缓存交换的时间和显示器刷新时间保持同步,帧缓存中的画面将会延后一个刷新周期被显示出来。在使用 60Hz 显示器时,一个刷新周期的时间高达 16.67ms,也就是说本来一秒五帧的图像延迟只有 3.3ms,现在因为要干等一个刷新周期,延迟一下子就增加到了 13.3ms,对于连 5ms 和 1ms 显示器都能分清的电竞选手而言,这多出来的10毫秒延迟是非常要命的。


                  IP属地:上海9楼2017-03-28 13:31
                  回复
                    - 哎呀,不开垂直同步会画面撕裂,开了又会有延迟,那画质和性能就不能兼得吗?
                    - 能啊,要想画质与操作兼得,有两个办法
                    第一个办法,买个 G-SYNC 或 FreeSync 的电竞显示器

                    这些显示器可以动态调整自己的刷新率,使其和显卡输出画面的帧率完全同步,这样不仅可以在解决画面撕裂的同时不出现操作延迟,还可以在帧率低于 60fps 的情况下同样提供垂直同步的效果,消除画面撕裂。不过,这毕竟是个要花大钱的办法,而且据我所知,几乎没有哪个电竞屏的屏幕素质是很优秀的,为了达到低延迟,许多电竞屏都采用了 TN 面板,对于电竞选手而言当然无可厚非,但对我这样的画面党来说,这样的屏幕看起来就有点难以接受了。


                    IP属地:上海10楼2017-03-28 13:31
                    收起回复
                      第二个办法,相信大家已经猜到了:三重缓冲!

                      既然垂直同步的延迟是因为显卡输出完一幅图像就歇着等待红绿灯了,无法响应鼠标键盘最新的操作,那么我们为啥不让显卡一直工作呢?这样不就能一直响应最新的输入操作了吗?三重缓冲就是基于这种思路设计的,它在双重缓冲的基础上再加入了一个帧缓冲区,组成了一个前缓冲区,两个后缓冲区的规格。程序来回向两个后缓冲区写入图像,每次显示器刷新时,前缓冲区就和最近完成写入的那个后缓冲区交换。可以看到,即便有一个缓冲区要受到红绿灯的管控,另外两个缓冲区还是可以来回写入图像,于是就不需要人为增加画面延迟了。


                      IP属地:上海11楼2017-03-28 13:32
                      回复

                        这张图便说明了三重缓冲的原理,这种方法结合了前两种的优点。
                        不过三重缓冲也并非完美无瑕。首先由于需要一个额外的帧缓冲区,因此它会占用更多的显存空间。比如我们在 4K 分辨率下运行《质量效应:仙女座》,三重缓冲额外占用了约 200MB 的显存,对我们而言尚可接受。其次,它的延迟虽然远远低于双重缓冲下的垂直同步,但相比不开垂直同步还是可能略微高一点,因为无垂直同步的画面在给你带来撕裂的同时,也会包含最新帧的图像,如果开启了三重缓冲,那么画面中这“后面一帧“的多余元素就会被剔除,延迟自然会略微高于前者一点点。不过和满屏的画面撕裂相比,我显然还是会选择三重缓冲的……
                        看到这里,你肯定迫不及待地想要开启三重缓冲了吧,的确,垂直同步+三重缓冲是种非常棒的技术,可以有效地改善画面撕裂,同时不造成画面延迟。但是问题来了,DirectX 并不原生支持三重缓冲!而是使用了一种叫“预渲染队列“的方式。这种方式与三重缓冲不同的地方在于,它不会丢弃显卡渲染完却未被使用的帧(即过时的帧),而会强制将这些旧帧显示出来,因此会造成更大的操作延迟,甚至比光开垂直同步的延迟还要大。DirectX 的游戏若想使用三重缓冲,需要游戏厂商提供相应的支持。
                        很可惜的是,不少采用 DX API 游戏虽然在画面选项里提供了”三重缓冲“选项,实际上却是使用了“包含 3 个缓存空间的预渲染队列”,这些游戏使用的到底是不是真正的三重缓冲,只有你亲身体验后才能弄明白。所以,能不能开启三重缓冲,还要看游戏厂商的心情啊!


                        IP属地:上海12楼2017-03-28 13:32
                        回复(1)
                          ▌总结:
                          垂直同步和三重缓冲到底该不该开呢?如果游戏支持,条件允许的话(对于 60Hz 显示器的用户,显卡能跑到 60 帧以上),还是尽量开起来试试。但如果你的显卡达不到这么高的速度,或者你经过试验发现某一款游戏在三重缓冲下的操作延迟依然很高,那还是把它关了吧。
                          本文的阅读难度不低,如果大家有任何疑惑都可以给我们留言,我们在之后会考虑将本文做成视频的形式,以便更形象地向大家说明“垂直同步”和“三重缓冲”的工作原理。
                          如果各位有任何其他的名词希望我们解释,也可以告诉我们哦!
                          最后附上参考资料,欢迎大家参阅
                          原文来自外媒Anandtech:
                          Triple Buffering: Why We Love It
                          www.anandtech.com/show/2794/


                          IP属地:上海13楼2017-03-28 13:33
                          收起回复
                            前排


                            IP属地:广东来自Android客户端14楼2017-03-28 13:33
                            回复
                              也并没有什么卵用


                              IP属地:广东来自Android客户端15楼2017-03-28 13:38
                              回复