1977 年至 2017 年计算机延迟情况

我老是有这个感觉:我今天使用的计算机感觉比小时候使用的计算机来得慢。我信不过这种感觉,因为结果往往证明人类的感觉在实证研究中是不可靠的,所以我带上一只高速相机,测量了我在过去几个月遇到的一些设备的响应延迟。结果如下:

这些是键入字符与终端显示字符之间的延迟的测试结果(更多细节详见附录)。测试结果按最快到最慢排序。在延迟这一列,随着设备速度变慢,背景颜色从绿色变成黄色、红色直至变成黑色;也就是说,随着设备速度变慢,背景颜色变暗。没有一款设备的结果呈绿色。在同一台机器上测试多个操作系统时,操作系统以粗体显示。在同一台机器上测试多个刷新率时,刷新率以斜体显示。

在年份这一列,随着设备变得陈旧,背景颜色变暗、变紫。如果较旧的设备速度较慢,那么我们在阅读该图表时,会看到年份这一列变暗。

接下来两列显示了处理器的时钟速度和晶体管数量。较小的数值较暗、较蓝。与上面一样,如果较慢的主频和较小的芯片与较长的延迟有关,我们在阅读该表格时,会看到这几列变暗,但要说有什么区别的话,似乎恰好反过来。

作为参考,表格中添入了一个数据包通过光纤绕遍全球,即从纽约市(经由东京和伦敦)传回到纽约市的延迟。

如果我们看一下整体结果,最快的机器是旧机器。较新的机器良莠不齐。屏幕刷新率异常高的高端游戏机几乎与上世纪70年代末80年代初的机器有得一拼,但是“普通”的现代计算机无法与三四十年前的机器相竞争。

我们还可以看看移动设备。在这种情况下,我们将关注浏览器中的滚动延迟:

如上所述,结果按照延迟来排序,随着设备速度变慢,颜色从绿色变成黄色、红色直至变成黑色。同样如上所述,随着设备变旧,年份这一列会变得更紫、更暗。

如果我们排除game boy color(这类设备与其余设备不一样),所有最快的设备都是苹果手机或平板电脑。下一个最快的设备是blackberry q10。虽然我们没有足够的数据来确切地表明为什么blackberry q10的速度就非苹果设备而言很快,不过一个合理的猜测是,它有实体按钮,这大有帮助;实体按钮比触摸屏更容易做到延迟低。配备实体按钮的另外两个设备是gameboy color和kindle4。

除了iphones和非kindle按钮设备,我们还有年头不一的各种Android设备。靠近表格底部的是古老的palm pilot 1000,后面是kindles。palm受制于在触摸屏技术慢得多的时代研制出来的触摸屏和显示屏,kindles使用比现代手机上使用的屏幕慢得多的电子墨水屏幕,所以看到这些设备出现在表格底部也就不足为奇了。

为什么apple 2e这么快?

与不是最新款ipad pro的现代计算机相比,apple2在输入和输出方面都具有显著优势;除了最精心编写的代码外,它在输入和输出之间也具有优势,因为apple 2不必处理上下文切换、不同进程之间的交接所需要的缓冲区等等。

在输入方面,如果我们看一下现代键盘,常常看到它们以100Hz至200Hz的速度扫描输入内容(比如说,ergodox声称以167Hz的速度扫描)。相比之下,apple2e实际上以556 Hz的速度扫描。详情请参阅附录。

如果我们看看另一头的屏幕,我们也可以在这里发现延迟变长。我有块屏幕号称切换时间仅为1ms,但如果我们看看从最初看到字符的痕迹出现在屏幕上到字符实实在在地呈现,屏幕实际显示字符用时多少,那么它很可能10ms。声称延迟较低的一些高刷新率屏幕甚至也存在着这种情况。

在144 Hz下,每帧用时7ms。屏幕的变化会有0 ms至7ms的额外延迟,因为它在被渲染之前等待下一个帧边界(平均而言预计是最大延迟的一半,即3.5 ms)。除此之外,即使我的屏幕号称切换时间只有1ms,但是一旦屏幕开始改变颜色,实际上似乎需要10 ms才能完全改变颜色。如果我们将等待下一帧的延迟与实际颜色变化的延迟相加,预计延迟就会是7/2 + 10 = 13.5ms

如果是apple 2e中的旧CRT,我们预计60Hz刷新率的一半(16.7ms/ 2,加上可忽略的延迟),即8.3ms。这个成绩今天很难击败:最先进的“游戏显示器”可以将总的显示延迟降低到同样的范围,但是就市场份额而言,很少有人拥有这样的屏幕,连号称速度很快的屏幕也并非总是实际上很快。

iOS渲染管道

如果我们看看输入和输出之间发生了什么,会发现现代系统与apple 2e之间的差异太太了,简直可以写一整本书。为了了解现代机器的情况,前iOS/UIKit工程师安迪•马图斯查克(Andy Matuschak)大致介绍了iOS上面的情况(https://andymatuschak.org/),他事先声明:“这是我对过期信息的过时记忆”:

硬件有自己的扫描速率(比如最新触摸面板是120Hz),所以那会增加多达8 ms的延迟;

事件通过固件传递给内核;这个过程比较快,但系统调度问题可能会在这里增加几个ms;

内核通过mach端口将那些事件传递给特权用户(这里是backboardd);可能会有更多的调度损耗;

backboardd必须确定哪个进程应接收事件;这需要对窗口服务器进行锁定,窗口服务器共享该信息(需要返回到内核,增加了调度延迟);

backboardd将该事件发送给相应进程;在处理之前可能会有更多的调度延迟;

那些事件只在主线程上离开队列(dequeued);主线程上可能会出现其他情况(比如,由于计时器或网络活动),所以可能增加更多的延迟,这取决于具体工作;

UIKit增加了1-2ms的事件处理开销,受CPU限制;

应用程序决定如何处理该事件;应用程序写得很糟糕,所以这通常需要好多ms。结果在事件驱动型更新中进行批处理,该更新通过IPC发送到渲染服务器;

如果应用程序因该事件而需要新的共享内存视频缓冲区,那将需要通过IPC往返渲染服务器,这增加了调度延迟;

(次要变化是指渲染服务器自身可以处理的变化,比如仿射转换变化或图层颜色变化;非次要变化包括需要处理文本、大部分光栅和矢量操作的任何变化);

这些种类的更新通常最终会三重缓冲:GPU可能使用一个缓冲区来即时渲染;渲染服务器可能为下一个帧将另一个缓冲区排队;你想要使用另一个缓冲器。这里有更多的(跨进程)锁定;更多趟访问内核。

渲染服务器将这些更新添加到渲染树(几ms)

每NHz,渲染树被倒出到GPU,GPU被要求填充视频缓冲区;

不过实际上,屏幕缓冲区常常有三重缓冲,这与前面介绍的原因一样:GPU使用一个缓冲器,可能为准备另一个帧而读取另一个缓冲器;

每NHz,视频缓冲区与另一个视频缓冲区交换,屏幕直接由该内存来驱动;

(这个NHz未必与前一步的N Hz完全一致)

安迪说:“这里发生的实际工作量通常很小。只有几ms的CPU时间。主要开销来自:

定期扫描速率(输入设备、渲染服务器和屏幕)不完全一致;

跨进程边界的许多交接,每次交接都让别的东西(而不是输入事件的结果)有机会得到调度;

大量锁定,尤其是跨进程边界,势必需要进入到内核。

相比之下,在apple 2e上,基本上没有交接、锁定或进程边界。一些很简单的代码运行并将结果写入到屏幕内存,这导致屏幕在下一次扫描时予以更新。

刷新率与延迟

计算机结果让人感到好奇的一方面是刷新率的影响。从24 Hz到165Hz,我们改善了90 ms。在24 Hz下,每帧需要41.67ms;在165 Hz下,每帧需要6.061 ms。正如我们上面看到的那样,要是没有任何缓冲,我们预计在前一种情况下帧刷新增加的平均延迟为20.8ms,后一种情况下为3.03ms(因为我们期望获得帧的统一随机点,等待时间在0ms到全帧时间之间),这大约相差18ms。但实际上相差90ms,这意味着延迟相当于(90- 18)/(41.67 - 6.061)=2缓冲帧。

如果我们根据同一台机器上的其他刷新率绘制结果,就可以看到:如果我们假设,对于运行powershell的机器而言,无论刷新率如何,我们都会得到2.5帧的延迟,这些结果大致符合“最佳拟合”曲线。这让我们得以估计如果我们为这款低延迟游戏机配备infinity Hz屏幕,延迟将会多少――我们预计延迟为140 - 2.5 * 41.67 = 36 ms,与上世纪七八十年代快速但标准的机器一样快。

复杂性

现在人们购买的几乎所有计算机和移动设备都比上世纪七八十年代普通型号的计算机要慢。低延迟的游戏台式机和ipad pro其延迟与三四十年前的快速机器在同一个区间,而大多数非专门设计的设备相差甚远。

如果我们非要为延迟变长找出一个根源,可以说归因于“复杂性”。当然,我们都知道复杂性不好。如果你在过去的十年参加过非学术性非企业技术大会,很可能起码有一场会专门探讨复杂性为何是万恶之源、我们应如何竭力降低复杂性。

遗憾的是,消除复杂性比谈论我们应消除复杂性要困难得多。许多复杂性直接或间接地为我们换来了某种功能。如果我们看一下现代键盘与apple 2键盘的输入,发现使用功能相对强大、价格相对昂贵的通用处理器来处理键盘输入可能要比键盘的专用逻辑部件来得慢,后者来得更简单更便宜。然而,使用处理器让人们能够轻松定制键盘,并且将键盘“编程”这个问题由硬盘交给软件,这降低了制造键盘的成本。较昂贵的芯片增加了制造成本,但考虑到这些小批量手工键盘的成本有多少是设计成本,以制造成本换易于编程是净赢(net win)。

我们在整个环节的每个部分都看到这种取舍。一个最明显的例子就是你可能在现代桌面上运行的操作系统与在apple 2上运行的循环(loop)。现代操作系统让程序员可以编写通用代码,以处理其他程序在同一台机器上同时运行这种情况,并确保相当好的基本性能,但是我们为此在复杂性方面付出了巨大代价,简化这个过程中要做的交接大大增加了延迟。

许多复杂性可以称之为偶发复杂性(accidental complexity),但大部分的偶发复杂性之所以会存在,是由于那样很方便。在各个层面:从硬件架构、系统调用接口到我们使用的I/O框架,我们都在应对复杂性;如果今天我们可以坐下来,重新编写所有系统及其接口,有望消除大部分复杂性,但是重新发明世界以减小复杂性太不方便了,我们得益于规模经济效益,于是我们忍受现有的复杂性。

实际上,由于诸如此类的原因,解决“过度”复杂性引起的性能差这个问题的办法常常是增加复杂性。尤其是,让我们想到三四十年前最快机器速度之快的性能提升不是来自听取告诫以降低复杂性,而是来自增加复杂性。

ipad pro堪称现代工程的壮举;用来为输入和输出提高刷新率以及确保软件管道没有不必要的缓冲的工程技术很复杂!设计和制造可降低系统延迟的高刷新率屏幕同样也很复杂,那是普通60 Hz屏幕所无法企及的。

在竭力降低延迟时,这实际上是个常见话题。降低延迟的一个常用技巧是添加缓存,但是为系统添加缓存会让系统更复杂。对于生成新数据,无法容忍缓存的系统来说,解决方案常常更为复杂。这方面的一个例子就是大规模的RoCE(基于融合以太网的RDMA)部署。虽然这些方法可以将远程数据访问延迟从毫秒级降低到微秒级,从而支持全新类型的应用。但这么做的一大代价就是复杂性加大。早期大规模的RoCE部署很可能要花数十人年才能够搞好,而且在运营方面带来了巨大的负担。

结论

这多少有点荒谬:即使我们拥有刷新率高出近3倍的显示器,但在认真编写代码的每个应用软件中,哪怕运行速度4000倍于apple 2,CPU所含晶体管数量500000倍(GPU的晶体管数量多出2000000倍),现代游戏机的延迟还是与apple 2大致相当。可能更加荒谬的是,owerspec g405的默认配置(2017年10月之前拥有市面上最高的单线程性能)从键盘到屏幕(约3英尺,实际连线可能是10英尺)带来的延迟比让数据包跑遍全世界(从纽约到东京、到伦敦再回到纽约共16187英里,由于铺设尽可能短的光纤的成本,可能延迟增加30%)。

从好的方面来看,我们可能会告别延迟黑暗时代,现在就可以组装或购买一台延迟与七八十年代你能获得的非专门设计设备一样的平板电脑。这让我想起了注重屏幕分辨率与密度的那个黑暗时代:就在不久前,90年代的CRT提供比价格合理的非笔记本电脑LCD更好的分辨率和更高的像素密度。4k屏幕现在变成了司空见惯、价格合理的8k屏幕,效果远胜我们之前在消费级CRT上见到的效果 =。我不知道在延迟方面我们会不会看到同样的改进,值得期待。

附录:为什么测量延迟?

延迟很重要!就很简单的任务而言,人们察觉得出2 ms或更短的延迟。此外,延迟增加不仅会让用户有所注意,还会导致用户不太准确地执行简单的任务。如果你想看看直观地演示延迟是什么样子,身边又没有一台快速的旧计算机,可以看看微软研究公司的这段触摸屏延迟演示。

吞吐量也很重要,但这个指标已广为人知和测量。如果你访问几乎任何主流的测评或基准测试网站,会找到一大堆的吞吐量测量结果,所以我没必要写另外的吞吐量测量结果。

附录:apple 2键盘

apple 2e不是使用编程的微控制器来读取键盘,而是使用为读取键盘输入设计的一种简单得多的定制芯片:AY 3600。如果我们看一下AY3600数据表(https://danluu.com/AY3600.pdf),就会发现:扫描时间是(90 * 1/f),去抖动时间被标为strobe_delay。这些数值由一些电容和一个电阻决定,apple 2e的相关数值似乎是47pf、100kohms和0.022uf。将这些数字插入到AY3600数据表中,我们可以看到f= 50kHz,因而得出1.8ms的扫描延迟和6.8ms的去抖动延迟(假设数值准确,电容性能会逐级降低,所以我们预计旧apple 2e上的实际延迟更低),因而内部键盘逻辑部件的延迟低于8.6 ms。

相比于扫描速率为167 Hz、多扫描两次以便去抖动的键盘(https://www.arduino.cc/en/Tutorial/Debounce),对应的数字是3* 6 ms = 18 ms。若扫描速率为100Hz,那就成了3 * 10 ms = 30 ms。18ms至 30 ms的键盘扫描加上去抖动延迟与我们在进行初步的键盘延迟测量时看到的延迟相一致。

作为参考,ergodox使用搭载80000只晶体管的16MHz微控制器,而apple2e CPU是搭载3500只晶体管的1MHz芯片。

附录:实验装置

大多数测量用的是240fps相机(4.167ms分辨率)。响应时间低于40 ms的设备用1000fps相机(1ms分辨率)重新加以测量。表上的结果是多次测量的结果,四舍五入到最接近的10 ms,避免虚假准确性。至于桌面结果,从键开始移动直到屏幕完成更新来测量结果。请注意,这不同于你在网上看到的大多数键盘输入到屏幕更新的测量,后者通常使用实际上消除大部分或所有键盘延迟的装置;作为一种端到端测量,只有你与计算机有心灵感应,这样的测量才有可能成为现实。另一大区别是,测量是在尽可能接近默认操作系统设置的情况下完成的,因为几乎没有一个用户会捣鼓屏幕设置以减少缓冲、禁用合成器等设置。

计算机的结果是使用系统的“默认”终端来获得的,这很可能导致快速终端与慢速终端相差20 ms至30ms。

powerspec g405的基准测试结果使用集成显卡(该机器不带显卡),60 Hz是廉价显卡的结果。

移动结果是用这种方法获得的:使用默认浏览器,浏览至https://danluu.com,测量从手指移动到屏幕首次更新以表明滚动已发生的延迟。

在“平分”的情况下,结果按未四舍五入的延迟这个决胜指标来排序,但不应该认为这个指标很重要。可能也不应该认为相差10 ms很重要。

定制的haswell-e在gsync开启的情况下加以测试,没有明显的区别。这台机器的年份有点随意,因为CPU是2014年的,但是屏幕比较新(我认为到2015年你才有165 Hz屏幕。)

一些现代机器的晶体管数量只是粗略估计,因为确切的数字未公开。如果你有更精确的估计,请随时联系我!

延迟和年份的色标是线性的,时钟速度和晶体管数量的色标是对数标尺。

云头条编译、未经授权谢绝转载

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171225A10KMX00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券