原文: Flipping the FLOPS - how ARM measures GPU compute performance
玩转 FLOPS – ARM 如何测量 GPU 计算性能
作者: jemdavies / 2013 年 5 月 15 日上午 8:48 /
现在是时候来谈谈 GPU 中计算性能的测量了。作为旨在为图形行业启蒙与释疑的一系列 ARM 博文中的又一篇,我想谈谈每秒浮点运算数(FLOPS,或者 GFLOPS 或 TFLOPS)的问题。
在过去, tomolson 探讨过每秒三角形数(“无用的图形处理器性能指标”), edplowman 谈论过每秒像素数(“关于原理与像素非像素的情况“),Sean Ellis 阐述过浮点运算精度(“熟练掌控数值范围 - 浮点数格式在图形中的重要性”),希望我们在教育的同时又愉悦了大众。今天,我们来看看计算性能 - 它是一种有用的指标。
竞争是好的… … 但开放而诚实的竞争更好。GPU 市场竞争激烈,有些公司提供 IP,另一些则自己生产,以跻身于 SoC 竞争中。我爱竞争,没有竞争哪来胜利呢?或者,正如竞争力最强的某人曾经跟我说过:“不赢的话,竞争有什么意义?”(她是一名运动员,但一言以蔽之,这里有许多人想要在他们为之付出的事业中取得胜利。)在这竞争环境之中,我们知道我们的合作伙伴有时要努力了解 GPU 的性能指标。他们需要比较多家供应商的产品,从中找出满足他们需求的一个。这可能是个复杂的话题,但其实也不必像有些人试图制造的那么复杂。我希望通过诚实而开放的指标赢得竞争…
图形是计算 图形实际上是计算密集型问题 - 你必须在其中执行许许多多运算,这也是人们感兴趣于不“仅仅”是利用这些功能来处理图形的原因之一。要绘制图形,我们首先在三维空间中描述一些对象,把这些对象分割为许多三角形,列出三角形中每个顶点的坐标。我们可以争论为何要使用三角形,的确有这样的争论,但三角形比较简单,其中的三个点组成一个确定的平面。接着我们定义一些光源,给予它们类型和位置;我们定义投影模型(摄像机)并给予它一个位置;我们为(组成那些三角形的)对象定义颜色和表面细节。有时,我们添加更多细节;有时,我们为对象制作动画,使它们运动起来。所有这一切之后,我们尝试制作出从该摄像机拍摄的照片,就如它投影到一个二维屏幕上一样。正如你想象的那样,有许多 3-D 等式要处理,还有许多三角函数。我们使用的大多数数字是浮点数,因此我们执行浮点运算的速度对图形性能有很大的影响。当然,这不是唯一的因素,却是很重要的。了解这一点当然很不错。
先描述问题
在我们的 GPU(以及许多其他 GPU)中,上述所有位置中都执行浮点运算。有些是固定函数单元,有些则是可编程单元。此处的一些示例可能有所帮助:在你加载纹理的值时,纹理单元将根据你指定的纹理中的坐标计算内存地址,然后可能在内存中的多个值之间插值,产生你需要的纹理,或许在一些相邻的值之间双线性地进行过滤(做双线性滤波)。而且,如果纹理是 ASTC 等压缩格式,作为该过程的一部分,这些值还必须解压缩。这包含许许多多的计算(整数和浮点数)。对图像而言这很不错,但将这些单元用于更加普通的计算则有点难甚至不可能。
一些 GPU“只”负责图形,不做一般计算。例如,Mali-400 系列的设计面向 OpenGL ES 2.0,其精度要求较低。一些运算需要以 32 位精度执行,一些需要 24 位,另一些则需要 16 位。ARM CPU 的 NEON 上的 OpenCL 可以用作计算指南(可协助进行计算)。
一些 GPU 同时负责图形和计算。例如,Mali-T600 系列 GPU 使用 Midgard 架构(我在上一篇博文中进行了介绍)。在这一架构中,我们有运算(算术)流水线,可以执行 ADD 和 MUL 等指令。我们均衡地混合了标量和矢量 (SIMD) 单元,因此可以像并行处理一样执行多个运算(例如,4 个 FP32,8 个 FP16)。我们也有点乘积指令,以及一组三角函数指令(如 sin、cos 和 tan 等)。你应如何表达 sin() 等三角函数中的浮点运算数量?
Mali-T600 系列是为计算而设计,并且拥有(支持)最新的图形 API,如 OpenCL、OpenGL ES 3.0 和 Microsoft DirectX11,因此它支持完整的 32 位精度浮点运算(符合 IEEE-754-2008 标准)。我们还进行双精度(64 位浮点)运算;而且,顺便提一下,我们也可执行包括 64 位在内的各种整数运算(传统的 GPU 缺乏良好的整数功能)。
总而言之,我们的 GPU 拥有不同的整数和浮点运算性能级别,不同的精度,以及不同的代码利用能力级别。
然后,定义你的指标
现在,该说说这个棘手问题了:如何定义测量 GPU 中进行多少运算的指标:要测量的是什么?目前在 ARM,我们希望包揽一切:毕竟,合作是我们的一件大事情。所以,我已准备好走到这么远:你做什么不那么重要,只要你能展示你的工作(正如英国老师对学生所说的那样,也就是说明你使用的方法)。然而,不说明其数字(即使在附属细则中)的人肯定是在尝试隐藏些什么,结果是什么也藏不了。因此,秉持开放的精神,我们是如何得到我们的数字的?好吧,既然标题是与 FLOPS 相关,此刻我们要把整数运算放到一边。以下是 ARM 的规则:
我们不做的事情 ARM 不包含固定函数单元的 FLOPS,或者仅从图形中可用的元素(也不包括图形专用单元的运算能力),如纹理单元、混合单元、可变插值、三角形设定和 Z 轴压缩等。
最后, 我已描述了我们是如何定义和生成我们的架构 FLOPS 数的。它应当为你提供了所需的武器,你可以去质疑你供应商计算其结果的方式。希望这将带来实用、有建设性的对话。或许,我们需要一个标准。或许,这将导致我们改变定义数字的方式来迎合别人的方法。这没关系,只要我们对此开诚布公。
我也说明了基准测试在说明现实世界性能中需要扮演的角色。我们需要让业界对哪种基准测试有意义达成共识。太多的基准测试可能会带来困惑。
喜欢我们的方式吗?或者讨厌?认为我们不对?想要建议一些不同看法?想要讲讲别人是怎么做的?请告诉我们。欢迎评论这篇博文。