泡泡网显卡频道 PCPOP首页      /      显卡     /      新闻    /    正文

游戏延迟解读 fraps测卡顿其实不靠谱

  解释帧时间之前需要先了解一下Windows系统的渲染过程(Rendering Pipeline)。渲染过程本身并不复杂,但是因为要涉及到Windows系统、CPU、GPU以及驱动等层面,需要知道是哪个环节出了问题才造成延迟的。
 
  从基本原理上看,渲染主要有3个过程,应用程序需要将数据传递给Windows系统,Windows则通过驱动管理这个处理过程,最后等系统和驱动准备完成了,GPU就会输出一帧图像并显示出来。

  长话短说,Windows系统中负责管理的就是Direct3D API,它是DX API中最主要的3D渲染API,是一个庞大的、复杂的API命令与函数的的集合。D3D首先也是最主要的作用就是收集应用程序的各种绘制命令(draw),并将其结合起来,为进一步的工作做处理。一旦某个完整帧的帧绘制命令都收集完了,D3D就会把它处理完成的工作传递给显卡驱动堆栈的第一个组成部分——UMD( User Mode Driver)。
 
  UMD主要负责D3D的输出,并将其变成GPU可以处理的工作批次(work batches)。这些工作批次、命令缓冲器(也叫做显示列表,Display Lists)都是适合目前GPU处理的指令及数据的集合。
 
  UMD另外一个工作就是着色器编译(shader compilation)以及将正确而且最适合的表面格式(surface formats)分配给GPU。

  UMD的工作完成之后,它就会把命令缓冲器传递回D3D,D3D再依次把命令交给上下文队列(context queue),这是可能会造成卡顿的第一个瓶颈,至于它为什么会造成瓶颈,后面还会继续讲到。

  上下文队列之上还有GPU调度器,它负责管理原本应该通过context queue送到KMD( kernel mode GPU driver)而实际上却脱离的命令缓冲导致的爆音(popping)意外。
 
  通过上面的一系列过程我们在GPU的后端缓冲器里最终渲染出了一帧完整的图像,但是这一帧并不会自动输出到显示设备上,命令缓冲器批次的最后一步是Direct3D Present,Present命令的作用就是告诉GPU将后端缓冲器发到前端,然后将渲染的图像输出给用户,只有present指令执行完之后图像才会输出。
 
  以上就是一个3D渲染过程的简单介绍,下面我们再来看看什么是真正的帧延迟。

延迟的真正定义
 
  卡顿(shutting)的定义有很多,实际中我们一般这么定义:任何可能导致每帧时间显著变化的情况都可以定义为卡顿,这是一个通用的定义,但是造成卡顿的情况有很多,还得分别来看。
 
  Anandtech将卡顿分为单卡卡顿和多卡卡顿两个部分来讲,不过首先还是看各种可能造成卡顿的原因。如果GPU用了超过预期的时间(要知道不可能先于时间精确预计需要渲染多少次)来渲染图像这就会造成卡顿;如果驱动程序需要等待很长时间才能为GPU准备好需要渲染的某一帧,这也会造成卡顿;如果游戏的仿真步长( simulation step)用了很长时间也会导致卡顿;如果CPU/OS太忙导致不能预期发送指令也会导致卡顿,总之就是造成卡顿有各种可能,每一个步骤出了意外情况都可能导致卡顿现象发生。
 
  而造成这些现象的根本原因是Windows系统并不是一个实时操作系统(real-time operating system),这意味着它不能在某个周期内执行任意的一条指令,只有当它准备好执行的时候才可以进行操作。为了达到这种毫秒级的反应,应用和驱动程序需要确保每个过程都是平滑进行的。
 
  虽然Windows系统一直在努力保证各项工作都是即时进行的,但是要知道PC是由各种各样的硬件组成的,种类和数量都非常庞大,这就造成了它很难消除卡顿。
 
  最回到我们的问题上来,如果禁用了垂直同步,卡顿就是一个很常见(虽然不是一直出现)的问题。如果开了垂直同步,以目前LCD的60Hz刷新率来算,平均生成每帧至少需要16.6ms。由于60fps这个限制,开了垂直同步之后,任何低于16.6ms的帧生成时间都会被阻挡在上下文队列中,这种固定16.6ms的帧时间就大大减少了卡顿现象。
 
  如果读者需要进一步了解垂直同步及三重缓冲的信息,可以翻阅几年前我们论坛版主privater翻译的Anandtech的另一篇文章
 
  三重缓冲:为什么我们爱它
 
  在讨论帧时间时我们还必须要区分两个定义,一个是延迟(latency),一个是帧间隔(frame interval)。延迟在这里的定义是指完整渲染完一帧图像的时间,而帧间隔跟延迟有关,但是又不同,它指的是每帧的间隔时间,典型的来说就是在渲染完成的末尾、正在显示的每帧间隔时间。

  这张图更好理解,延迟是完成一帧的渲染时间,帧间隔则是负责发送输出指令的两个present命令之间的时间。
 
  我们通常所说的卡顿实际上并不是这个延迟决定的,而是帧间隔(frame interval)时间决定的。帧延迟可以用独立测量出来,fraps软件就是最常用的工具了。我们这里谈的则是帧间隔。
 
  虽然我们可以建立一个存在帧间隔分割点的模型,在这个点上可以视其为卡顿或者不卡顿,但是帧间隔这个概念对每个人的感觉也是不同的,生成这一帧需要的时间比前一帧多了5ms,这样会导致卡顿吗?10ms?20ms?30ms?如果是在30fps vs 60fps之间呢?

  在与AMD的交谈中,AMD就提出了这样一个简单而又重要的问题:我们可以用工具客观测量出卡顿的存在,但是我们不能客观地衡量卡顿对每个用户的影响。
 
  下面的讨论就有点哲学味道了,总之Anandtech及AMD更倾向于认为卡顿这个事就算可以测量出来,但是它对每个人的影响也是很难评估的。
 
  在了解了3D渲染过程以及什么才是卡顿的真正定义之后,我们再回头看看frpas这类软件是如何捕捉延迟的,是否真的靠谱。

0人已赞

关注我们

泡泡网

手机扫码关注