原文: How low can you go? Building low-power, low-bandwidth ARM Mali GPUs
投稿人: Tom Olson,2012 年 8 月 17 日
能有多低?打造低功耗、低带宽 ARM Mali GPU
我刚从 SIGGRAPH 2012 这一全球顶级计算机图形大会回来,跟往年一样见识到了图形研究领域的最新成果,十分令人振奋。今年更是特别兴奋;除了沉浸在新成果中外,我也荣幸地(作为 OpenGL ES 委员会主席)宣布了全新 OpenGL ES 3.0 规范和 Khronos 标准版 ASTC 压缩技术的推出,并就移动 GPU 中功耗和带宽的话题在 SIGGRAPH 移动论坛上发表了演讲。在这篇博文中,我将回顾 SIGGRAPH 移动论坛演讲的要点。 我们钟爱谈论在图形性能方面“抬高标杆”。其概念是将 GPU 性能竞争比作跳高,你坚持不懈地努力刷新新的高度;不过,如果说到功耗和内存带宽,它就更像是林波舞比赛。该比赛的目标是不断地降低标杆,努力在减少所用能量的前提下保持相同的性能水平。事实上,这些目标是相同的;在两种情形中,你真正在努力做的都是最大化效率。想要更高的性能吗?你就必须降低能耗。想要更低的功耗吗?那么,你也实现了更高的性能。 一切关乎功耗 事实上,移动 GPU 的设计全都在于降低能耗。这个事实已存在一段时间,但其原因却在改变。我们之前担心过,因为我们关注电池续航时间。我们现在依然关心这个问题,因为谁也不希望在一天当中必须为移动设备充电;如果电池技术中的某种突破能够提供十倍于目前水平的电能存储容量,我们肯定会爱上它。然而,即使真的出现(不太可能),它也不能解决我们的问题,因为现在问题不在于电池续航时间,而在于发热。 现代高端应用处理器无一例外都受到热能限制。为处理器提供足够的工作来执行并且允许其尽可能快地运行,它们会因太多工作而使包装过度发热并毁掉自身。为了避免这种情况,它们包含许多智能的系统硬件和软件,在开始变得太热时强行使它们慢下来。请思考片刻;如果性能受限的原因不是晶体管太少,计算能力太低,或者内存访问不够,而在于你能够使用的能量,那么提高性能的唯一方式就是降低能耗。而且,要优化的最重要性能指标不是像素或每秒三角形数(但愿不会!),而是每像素纳焦耳量 (nJ/p)。 像 GPU 设计师一样思考 为了想象一下这种推理的结果,我们来看看功率优化的一个方面:减小内存带宽。既然我们在扮演工程师,那就使用数字来阐述;但别急,我们不需要高等数学和物理学 - 简单的算术就行。我们从一些简单事实开始:
第一个必须问的问题是,内存带宽使用足够的电能是否值得关心?我们第一个数字参数登场了:我们谈论的内存系统每秒传输 4 到 8 GB(千兆字节)数据。乘以每字节 150 pJ,结果是 0.6 到 1.2 瓦特。换而言之,内存带宽可以消耗我们整个功率预算。所以我们问题的答案是肯定的,内存带宽的确重要;事实上它是至关重要的。 区块游戏 在 SIGGRAPH 演讲中,我谈论了基于区块的渲染。这是一种组织图形流水线的方式,让颜色、深度和模板样本缓冲区留在芯片上。基于区块的渲染大大减小了内存带宽使用,尤其是当应用程序使用多采样抗锯齿 (MSAA) 时,它要求每个像素具有多个颜色、深度和模板样本。所有的 ARM® Mali™ GPU 中都使用它,Qualcomm Adreno™ 和 Imagination PowerVR™ 核心中也使用它(不同变体)。我们的版本原理如下: GPU 将输出图像分割为称作区块的小矩形,并且维护一份需要绘入每个区块的待处理事项列表。当应用程序要求 GPU 绘制三角形时,它其实没有这么做;而是算出哪些区块包含这个三角形可能覆盖的像素,然后将三角形添加到那些区块的待处理列表中。需要绘制像素时,GPU 逐一处理各个区块。它针对每个区块读取该待处理列表,然后按照顺序画出所有的三角形;但由于区块很小,它就能够在称为区块缓冲区的特殊片上内存中执行此操作。当所有三角形都画好后,它执行我们称作解析的操作:过滤颜色样本以便为每个像素生成一个颜色,再将像素颜色写入外部帧缓冲区中。(通常)不再需要颜色、深度和模板样本,因此 GPU 就可忘记它们,转到下一区块。图 1 显示图片中的样子。
图 1:基于区块的渲染。为绘制而提交的三角形写入到系统内存中的每区块待处理列表中。需要这些像素时,光栅化程序读取每个区块的待处理列表,再将它渲染到片上多采样 (MS) 深度 (Z) 与颜色 © 缓冲区。一个区块完成时,会被解析以获取像素颜色,然后写入片外帧缓冲区。在此图中,GPU 刚完成将区块 9 渲染到内部多采样区块缓冲区,并将解析后的图像写入到外部帧缓冲区。 减小纹理带宽 图 1 向我们显示,基于区块的渲染将大部分繁重数据流量(具体而言就是进出多采样 Z 和颜色缓冲区的流量)放到了 GPU 内的片上内存中。仍然穿过总线进入系统内存的最粗箭头表示纹理数据。优化的第一条法则是“处理最让你头疼的事情”,因此减小纹理带宽是我们需要关注的下一问题。 显然,这也正是激励我们投身于自适应可伸缩纹理压缩 (ASTC) 技术的因素。我们已写了几篇有关 ASTC 的博文,因此这里就不再赘述;如需其原理的精彩介绍,请阅读 seanellis 的优秀博文(基于我们的 HPG 文章)。ASTC 前沿的最新发展是 Khronos 集团已将 ASTC 的一个子集用作 Khronos 批准的 OpenGL 与 OpenGL ES 扩展。我们已宣布计划在新近推出的 Mali-T624 和 Mali-T678 GPU 中支持该扩展,其他几家 GPU 提供商也表达了类似的意向。由于我们已同意按照 Khronos 会员协议条款以免版税的方式许可相关专利,我们预计 ASTC 将在未来几年中应用到所有 ES 平台。 从开发人员的角度而言,ASTC 的精彩之处在于它允许压缩你能想象到的任何纹理。目前常用的格式(S3TC、PVRTC、ETC1 和 RGTC)仅提供有限数量的比特率,颜色组件数量的选择也不多。ASTC 几乎可提供你所需要的任何比特率,以及你喜欢的任何颜色组件数量,你可以选择标准(8 位)或 HDR(浮点),所有这一切的质量只有 BPTC 等外来高端格式才能与之媲美。这意味着,你将第一次能够考虑将应用程序使用的所有纹理都进行压缩。覆盖面上毫无“漏洞”;无论你的像素格式或质量要求为何,ASTC 都有与之匹配的格式。[脚注:好吧,所有规则都有例外。ASTC 无法压缩整数纹理,这种纹理是 OpenGL ES 3.0 中的新功能。给我们一些时间。] 我们预计开发人员将需要些许时间感受 ASTC,尤其是了解哪些使用案例需要哪种比特率。对于想要先人一步的开发人员,我们已发布了评估版编解码器程序包,包括源代码。希望你喜欢。 让区块化更出色 我们回头再看看图 1,我们通过使用基于区块的渲染来消除传入多采样缓冲区的外部流量,而且推出了 ASTC 来尽可能减少纹理提取流量。剩余的最大箭头是区块写回,我们将解析后的颜色样本从片上区块缓冲区写入到外部内存中的帧缓冲区。随着屏幕尺寸变大,这一步也越来越重要 – 你得相信我,屏幕会变得相当大。我们能够对区块写回做些什么吗? 在 Midgard GPU 架构的设计过程中,我们花费了大量时间观察应用程序行为,寻找降低功耗或提高性能的机会。我们惊讶地注意到一点,我们写出到内存的解析后像素常常与在前一帧中写的像素完全相同。也就是说,与区块对应的图像部分没有变化。架构师们觉得这很恼人;GPU 在消耗能量将数据写到内存中,而该数据原本已在那儿了。显而易见,如果我们能够检测到区块未有变化的情况,就能跳过写入该区块,从而降低功耗。 现在,在 GPU 执行组合网页或窗口系统等操作时,存在许多不会变化的像素,这不奇怪。但我们发现,即使第一人称射击(FPS)游戏这类我们认为整个画面是不停改变的应用,也存在大量冗余区块写操作;视频播放应用亦是如此。显然,对这种应用,你可能节省不了太多,但大多数时候这样的节省水平已经值得我们去尝试了。所以,我们决定在 Midgard 中攻克该问题,方法就是添加一项我们称为事务消除的功能。 事务消除功能简介 好吧,这不是地球上最酷的名称,但技术本身简单而精巧。每次 GPU 解析一整个区块的颜色样本时,它会计算出一个签名或校验和 – 一个敏感地依赖于被解析缓冲区中每个像素的短位串。它将各个签名写入到与输出颜色缓冲区关联的列表。下一次渲染到该缓冲区时,在解析各个区块后,它将新的签名与旧签名对比。如果签名未有变化,就会跳过写出该区块,因为像素已发生变化的可能性是非常、非常小的。
图 2:事务消除签名对比
图 2 展示了这一概念。对于签名匹配(绿色)的区块,我们可以跳过写该区块;这发生于(在这一假设案例中)天空盒、平视显示器的各部分,以及汽车的各部分。存在不匹配(红色)时,我们必须将该区块写入内存。 理论与实践吻合 根据我们的设计研究,我们预计事务消除功能对于浏览和 GUI 组合大有帮助,但在游戏方面功效稍弱。然而,我们现在已经能够将合作伙伴的硅晶片用于 Mali-T604,所以我们能够在真实的操作系统上运行的实际应用程序中研究这一行为。结果表明,成果比我们想象的还要好,原因有两个。首先,显示分辨率的增长又一次超出我们的预计;其次,人们玩的游戏并不是我们预期的那些类型。 拯救地球,一次一只 Angry Bird™ 目前,地球上最为流行的移动游戏就是 Rovio 的 Angry Birds,大大超越竞争对手。根据其开发商的数据,人们玩这一游戏的时间很长,全球大约每天 2 亿分钟。从统计上看,你似乎肯定已玩过,所以我就不必告诉你其样式对事务消除是友好的。但为了帮助你以视觉方式了解其友好度,这里有几幅图像(图 2、3 和 4)。我在存在签名不匹配的区块(因而必须将该区块写入内存中)上画了红色图层。如你所见,当我们瞄准弹弓时,运动很少,只需要写入一些区块。当我们发射小鸟时,整个画面平移,许多区块会变化,但我们最终依然能跳过大约 50% 的区块写操作。最后,当小鸟击中时,滚动变慢并且最终停止,活动区块的数量逐渐消失。
图 3:瞄准。事务消除功能可以免除 96% 的区块写操作。
图 4:飞行中的小鸟。此时有许多背景运动,但我们依然能够消除近一半的区块写操作。
图 5:降落。随着物理引擎的收敛,越来越多的场景变为静态,不再需要将区块写入内存。 那么,这有多大帮助? 为了得出事务消除值相关的数据,我们采集了游戏过程中 Angry Birds “Seasons” 发出的 OpenGL ES 命令的几千个帧。然后,我们在一款配有 Mali-T604 硅晶片的高端 Android™ 平板电脑原型机上运行这些命令,先是禁用事务消除功能,而后再启用该功能。我们使用内置的调试协议读回内部性能计数器。我们发现,在这一序列上消除了大约 75% 的区块写回。GPU 总带宽减少了近一半,从 6.5 MB/帧减少到 3.4 MB/帧。 放到现实中,如果地球上的每一位 Angry Birds 玩家使用的是 Mali 芯片(分辨率为 1368x760),并且假设带宽成本为每字节 150 pJ,该技术将为全球节省大约 3.8 kW 的电能。这足够为几幢单户住宅全天供电。它相当于大约五个马力,所以比 Vespa S 50 摩托车或者我的老旧 Sears 除草机的最大输出还要大。然而,从能源的角度来思考更加有趣。我们再假设每一位 Angry Birds 玩家都在使用该技术,事务消除功能将每年节约 34 兆瓦时的电能。如果你对拯救地球有所关注,这意味着 20 桶燃油,这些燃油将产生 8.7 公吨的二氧化碳;如果你更属于毁灭公爵型的人,它大概是 16.3 公吨炸药爆炸所释放的能量。很大一笔能源! 我希望以上对 GPU 设计和能源思维的小小深入讨论能让你有所收获。衷心感谢 Rovio 允许我使用 Angry Birds 的图像,也感谢他们编写了这一款非常适合事务消除功能的游戏,(当然)还有我生命中一去不复返的那数百小时时光… 有问题吗?想要辩论一番?请留言… Tom Olson 是 ARM 图形研究主管。在当过几年乐手(他没谈过这段经历)、多年为卫星设计数字逻辑之后,他获得了博士学位,并成为一名计算机视觉研究人员。大约在 2001 年,他意识到移动设备图形显示的需求浪潮即将到来,因此将自己的研究领域转向图形显示。在工作时间,他经常思考 ARM GPU 在 2013 年及之后的年份将用于何种用途。在业余时间,他主持 Khronos OpenGL ES 工作组。