gpu浮点计算能力floaps_基准测试移动 GPU 中的浮点精度 - 第 2 部分

投稿人:,2013年6月11日

这是有关GPU中浮点质量的一系列博文中的第二篇,我的灵感源自 发表于 的文章。在中,我宣称许多程序员其实并不真正了解浮点数字,也指出如果您准备将它用于比较棘手的东西,那么最好先准备好更加深入地了解其运作原理,甚至要超过您所希望达到的深度。我介绍了Stuart的测试,也说明它披露了GPU片段着色器中所用浮点精度的位数。这很有趣,但这个测试告诉我们的不止这些。在本文中,我将对此进行阐述。

测试与结果

Stuart的测试项目使用特殊的片段着色器来计算屏幕中每一像素的灰度浓度值。作为提醒,如下为我的版本。

precision highpfloat;

uniform vec2 resolution;

voidmain( void )

{

floaty= (gl_FragCoord.y/resolution.y) * 26.0;

floatx= 1.0 – (gl_FragCoord.x/resolution.x);

floatb=fract(pow( 2.0,floor(y) ) +x);

if(fract(y) >= 0.9)

b= 0.0;

gl_FragColor=vec4(b,b,b, 1.0 );

}

方框1:Youi Labs GPU精度着色器(稍有修改)

在上一篇博文中,我已详细说明了这段代码,所以这里仅总结一下:该着色器绘制由26个水平条纹组成的序列。每一条纹的灰度值理想状态下是从左侧1.0(白色)到右侧0.0(黑色)的线性斜坡。不过,灰度值受到了破坏,首先它被加上了2B(B 是该像素所处条纹的索引),而后又被丢弃了相加结果中的整数部分。这使得每一后续条纹中的灰度值精度减少1位,导致斜坡变得越来越凹凸不平。最后,所有位都被丢弃,条纹也变成全黑色。

在Stuart的博文中,他公布了这一着色器在6款移动GPU和1款高端桌面显卡上。图像的差异主要在两个方面。其一是非黑色条纹的数量;如我们上次发现的,该数字最终等于着色器引擎浮点有效数中小数位的数量。另一方面或许更引人注目:这些条纹在屏幕上生成的图案大有不同。这就是我今天要讨论的问题。

看看这些图像,它们似乎分成两大阵营:第一阵营由Nvidia Tegra 3、Vivante GC4000和Qualcomm Adreno 225组成,它们生成的条纹一直到屏幕左边缘都是白色,往右逐渐消失。其形状让我想起了虎鲸的背鳍,所以我把它叫做“逆戟鲸”图案(见图1)。另一阵营由NVIDIA桌面GPU和两款ARM MaliTM设备组成,它们生成对称的图案,我把它叫做“蜂窝”形(见图2)。(Imagination SGX544的表现稍有不同,但似乎也位列“蜂窝”阵营。)这些形状告诉我们什么?一方优于另一方吗?

图1:“逆戟鲸”图案(华为Ascend D1 / Vivante GC4000)

图2:“蜂窝”图案(Nexus 10 / Mali-T604)

在Stuart的博文中,他将许多条纹一直到屏幕左边缘都显示为白色视为良好的浮点质量。所以,他非常喜欢“逆戟鲸”GPU,对“蜂窝”阵营则不感冒。他尤其说道:

“左边缘的漂移表明计算中存在误差(本是白色的区域却为黑色),如果不加以考虑的话,将转换为令人不悦的视觉差错。”

他是正确的吗?要得出结果,我们必须探究在着色器运行时GPU的浮点单元内部会发生些什么;但在这之前,我们必须更进一步研究浮点的运作原理。

比您真正希望的还要细致,第2部分

在本系列的第1部分中,我快速介绍了通用单精度浮点格式,其带有8位指数和24位(包括隐藏位)有效数。最后我举了个例子,说明在将两个不同量度的数字相加时会发生什么,例如800万加11.3125。我们从这说起:

(-1)0 x 222 x 1.11101000010010000000000 = 8000000.0

(-1)0 x 23x 1.01101010000000000000000 = 11.3125

然后对齐二进制小数点,即向右偏移较小数字19位。在这之后,较小数字的二进制小数点左侧不再是平常的“1”位,所以我们说它被非规范化了。我们要相加的两个数字现在如下所示:

(-1)0 x 222 x 1.11101000010010000000000

(-1)0 x 222 x 0.00000000000000000010110(1010...0)

两者之和显而易见

(-1)0 x 222 x 1.11101000010010000010110(1010...0)= 8000011.3125

请注意,红色位不再能够装入有效数中。问题是我们该怎么处理它们?最简单的做法是把它们丢掉;在数学中,这叫做向零取整(RTZ)或截尾。这相当于假装红色位全都是零,尽管它们不是。将1转换为零会带来误差;在本例中,向零取整的结果是

(-1)0 x 222 x 1.11101000010010000010110 = 8000011.0

总误差是0.3125。想一下,如果所有红色位最初都是1,就会出现最糟糕的误差,此时我们给有效数带来的误差是

或者,大约是2-23。

如果愿意稍微用心一点的话,我们可以做得更好。我们可以不丢弃红色位,而是将它们向上或向下取整到24位有效数更接近的值。这么做被证明并不难:如果第一个红色位是零,我们与上述一样截尾(向下取整)。如果是1,并且至少还有一个红色位是1,我们向上取整。在上例中,我们理想的相加结果是

(-1)0 × 222 × 1.11101000010010000010110(1010...0)= 8000011.3125

向上取整为

(-1)0 x 222 x 1.11101000010010000010111 = 8000011.5

总误差是0.1875,比向零取整的结果稍微好一点。如果第一个红色位是1,而其他红色位都不是,正好在两个可代表的值中间;此时我们该怎么做?可能有各种打破僵局的规则;首选规则(也是 要求的默认规则)是朝着可以在有效数最低有效位中产生零的方向取整。这称为最近偶数取整 (RNE)。如果使用这一规则(或任何其他最近取整规则),最坏的误差是2-24,而不是2-23。这似乎没多少改善,但想想看:使用RNE而非RTZ可将最坏的误差砍掉一半。这很了不起;几乎像是免费获得了额外的一位精度。

总结时间

这与Stuart Russell的图像中的“逆戟鲸”和“蜂窝”又有什么关系呢?他的着色器(见上图方框1)所做的大致与我们在上一小节的示例中所做的相同:它将一系列逐渐变大的整数加到1.0到0.0之间的一组灰度值上,导致精度误差逐渐变大。我们思考第23条纹中发生了什么,在此我们要将灰度值与222相加。2的幂表示为

(-1)0 x 222 x 1.00000000000000000000000 = 4194304.0

我们在浮点数字系统中可以表示的下一个最大值是

(-1)0 x 222 x 1.00000000000000000000001 = 4194304.5

再下一个最大值是

(-1)0 x 222 × 1.00000000000000000000010 = 4194305.0

我们要与222相加的灰度值在零和1之间,所以浮点单元显然要将两者之和向三个值之一取整。做完加法后,着色器丢弃结果中的整数部分,所以剩余的仅仅是两个可能结果之一:0.0或0.5。

使用RTZ的GPU始终将正数值向下取整。所以,如果灰度值小于0.5,结果将向下取整到4194304.0,最终输出的灰度值为0.0。如果灰度值大于0.5,结果将(再次向下)取整到4194304.5,最终输出的灰度值为0.5。看看图1中最上方的可见条纹,这就是我们所发现的现象;条纹的右半部分(起始灰度值小于0.5)变为黑色,右半部分(起始灰度值大于0.5)变为50%灰色。“逆戟鲸”GPU使用的是向零取整!

另一方面,使用RNE的GPU将结果取整到它可表示的最接近值。当灰度值小于0.25时,相加结果将向下取整到4194304.0,因而生成黑色。当灰度值在0.25到0.75之间时,相加结果将取整到4194304.5,生成50%灰色。灰度值超过0.75时,相加结果将向上取整到4194305.0,逻辑上与白色对应;但是,在丢弃了结果中的整数部分时,最终再次生成黑色。这就是Stuart在其博文中提到的“从左边缘漂移”,也是我们在图2中看到的。“蜂窝”GPU使用的是最近取整。

为了让视觉化这一点变得稍微简单一些,我们可以修改着色器,以便在相加结果取整到整数时保留所生成的1.0灰度值。方框2显示这一代码,图3则显示了在另一个“蜂窝”GPU(AMD桌面产品(Radeon HD3650))上的运行结果。与图2相比,条纹现在可以一直延伸到图像的左边缘,而且出现了一个额外的第24条纹,其与最近取整(似乎)给我们带来的“额外一位精度”相对应。

precision highpfloat;

uniform vec2 resolution;

voidmain( void )

{

floaty= (gl_FragCoord.y/resolution.y) * 26.0;

floatx= 1.0 – (gl_FragCoord.x/resolution.x);

floatp=pow( 2.0,floor(y) );

floatb= (p+x) -p;

if(fract(y) >= 0.9)

b= 0.0;

gl_FragColor=vec4(b,b,b, 1.0 );

}

方框2:精度着色器修改后可在范围[0.0, 1.0]中生成输出

看这些图片是有趣的,但在本例中,如果我们标绘出“逆戟鲸”和“蜂窝”GPU上部几个条纹的输入和输出灰度值,则更容易发现区别。图4显示所获得的结果。(您看到的与图1和图3中的数据相同,至少对于第22-24个条纹是如此–我们仅将它看作图形,而不是灰度值。)我们看到了什么?RNE输出和输入的近似程度要优于RTZ输出;而且,其平均误差为零,而RTZ输出则有偏离(即平均误差不是零)。

还不确信吗?在图5中,我标绘出了RTZ和RNE曲线中的误差–即输出与输入之间差异的绝对值。如果稍作研究,在脑海中整合曲线下方的区域,您会高兴(但不惊讶!)地发现,在平均水平上,RNE方法产生的误差恰好是RTZ方法的一半。

图3:着色器修改后允许范围(0.0,1.0)中的灰度

谁的GPU拥有质量最高的浮点单位?

现在,我们终于可以解答这个问题:Stuart图像中的图形就他所测试的GPU中的浮点质量告诉了我们些什么?在他的观点中,它们意味着RTZ GPU(具体而言,Vivante GC4000和Qualcomm Adreno 225)生成质量最高的输出。但事实相反:执行RNE取整的GPU(如)生成的结果更为准确,误差更小。这也是为何最近偶数取整被指定为IEEE-754-2008中的默认取整方式。Stuart可以喜欢“逆戟鲸”图形而不是“蜂窝”;但这只能基于个人喜好,而不是质量。

然后呢?

对于Stuart的着色器,我真正喜欢的是它将比较难懂的浮点行为细节转换为引人注目的视觉图像。我们可否编写着色器为IEEE-754的其他死角做些类似的事?可以!下一次,我们将窥探一下令人畏惧的Zero Hole,看看一个能够表明您的GPU是否具备填补该漏洞的能力的着色器。在这之前–想要告诉问我为何定向取整确实要比最近取整好吗?想要为最近奇数取整来场充满激情的辩护吗?请与我联系…

Tom Olson是ARM图形研究主管。在当过几年乐手(他没谈过这段经历)、多年为卫星设计数字逻辑之后,他获得了博士学位,并成为一名计算机视觉研究人员。大约在2001年,他意识到移动设备图形显示的需求浪潮即将到来,因此将自己的研究领域转向图形显示。在工作时间,他经常思考ARM GPU在2013年及之后的年份将用于何种用途。在业余时间,他主持Khronos OpenGL ES工作组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556920.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

@DateTimeFormat注解

DateTimeFormat注解位于spring-context-5.0.10.RELEASE.jar包中 import org.springframework.format.annotation.DateTimeFormat; import java.util.Date;public class User {//姓名private String name;//出生日期DateTimeFormat(pattern "yyyy-MM-dd")private Da…

h5页面如何预览excel文件_移动端页面,如何解析预览 word/excel/PDF文件?

展开全部利用Office2007以上版本的一个PDF插件SaveAsPDFandXPS.exe可以导出PDF文件,然后再利用免费的swftools.exe工具生成swf格式的Flash文件,网页中加载flexpaper免费开源工具(32313133353236313431303231363533e59b9ee7ad9431333365633934有广告)实现…

Gson之toJson和fromJson方法

Gson是Google的一个开源项目,可以将Java对象转换成JSON,也可能将JSON转换成Java对象。 Gson里最重要的对象有2个Gson 和 GsonBuilder Gson有2个最基本的方法 toJson() – 转换java 对象到JSONfromJson() – 转换JSON到java对象 引入依赖:…

android 手机内存uri_android 的各种目录详解

App独立文件app独立文件就是那些不依赖于某特定app的文件这类文件当我们删除应用之后,还应该保留在手机上的,例如拍照的照片,不应该随着删除应用而被删除掉。这类文件应该是随着app删除而一起删除的,它们可以被存储在两个地方&…

python3 tkinter详解_python tkinter基本属性详解

1.外形尺寸尺寸单位:只用默认的像素或者其他字符类的值!,不要用英寸毫米之类的内容。btn tkinter.Button(root,text 按钮)# 设置按钮尺寸,绝大多数默认单位是像素btn.pack(ipadx 100,ipady 20)2.坐标系btn tkinter.Button(ro…

Gson详解(二)

1.复杂Json转成对象 比如:jsonString:{“response”:{“content”:"\n\t",“msg”:“成功”,“code”:“0”,“data{“content”:”\n\t",“VIN”:“LDC12345678901234”},“cmd”:“ScanVINCode”}} Gson解析 Gson gson new Gson();roodBean gs…

linux mysql 备份脚本_linux 之mysql备份脚本

#date 2020.2.20#author zhang#描述 用户自己选择使用什么工具进行备份#$1 账户; $2 密码 $3 地址stty erase "^H"[ -f /etc/init.d/functions ] && . /etc/init.d/functions#备份文件夹路径backup_path"/usr/local/src/backup_mysql"[ -d $backup…

Java使用GSON对JSON进行解析——IDEA引入jar包方式

GSON GSON是Google公司开发的用于解析json的类库。可以很轻松地让程序员将java对象转换成JSON格式,或者将JSON格式的对象转换成Java对象。 使用方法很简单: 首先,需要将GSON类库的jar包引入到自己的IDE中,本教程使用IDEA为例子…

mysql查询姓王的信息代码_MySQL查询语句练习题

1.创建student和score表CREATE TABLE student (id INT(10) NOT NULL UNIQUE PRIMARY KEY ,name VARCHAR(20) NOT NULL ,sex VARCHAR(4) ,birth YEAR,department VARCHAR(20) ,address VARCHAR(50));创建score表。SQL代码如下:CREATE TABLE score (i…

IoT -- (四) 物联网系统架构介绍

物联网系统框架介绍 下面将谈到几个关键问题: 设备如何接入网络?设备间如何通信?物联网数据的用途?如何搭建起一个物联网系统框架呢?它的技术架构又是怎么样呢?物联网终端软件系统架构?物联网云平台系统…

mysql 删除not null_从MySQL的列中删除NOT NULL限制?

要从MySQL的列中删除NOT NULL限制,请使用ALTER命令。语法如下:ALTER TABLE yourTableName MODIFY COLUMN yourColumnName dataType;为了理解上述语法,让我们创建一个表。创建表的查询如下:mysql> create table NotNullDemo->…

IoT -- (五) IoT都有哪些通信协议

IOT都有哪些通信协议? 在物联网协议中,我们一般分为两大类,一类是传输协议,一类是通信协议。那么,物联网都有哪些通信协议呢? 在物联网协议中,我们一般分为两大类,一类是传输协议&#xff0c…

IoT -- (六) MQTT和CoAP对比分析

IoT物联网需要标准协议,针对小设备最有前景的两种是MQTT和CoAP。 MQTT和CoAP两者均: 开放标准; 比HTTP更适合于受限环境; 提供异步传输机制; 在IP上运行; 有很多种实现 MQTT在传输模式上更为灵活&am…

mysql5.7.19不好用_Mysql 5.7.19 免安装版遇到的坑(收藏)

1、从官网下载64位zip文件。2、把zip解压到一个位置,此位置为安装为安装位置3、如果有以前的mysql 如果是install的,去控制面板卸载,还需要删除以前mysql留下来的残留文件。如果是免安装的,用mysqld -remove命令删除 ,…

IoT -- (八)MQTT优缺点

物联网并不仅仅是一种网络,而是一个新的生态环境,它描述的本质是越来越多的使用物品通过网络连接在一起并可使用单个或者多个的终端设备对它们进行各种控制和使用—当然,工业上的物联网通常连接到的石鼓传感器或者其他数据采集仪器以及行为单…

mysql 平滑扩容_数据库秒级平滑扩容架构方案

一、缘起(1)并发量大,流量大的互联网架构,一般来说,数据库上层都有一个服务层,服务层记录了“业务库名”与“数据库实例”的映射关系,通过数据库连接池向数据库路由sql语句以执行:如上图:服务层…

IoT -- (九) IoT通讯技术选型与模型设计

IoT时代的无线通讯技术 “世界上最遥远的距离就是没有网络”,网络通讯是IoT的基础,常见的无线网络通讯技术有:WiFi、NFC、ZigBee、Bluetooth、WWAN(Wireless Wide Area Network,包括GPRS、3G、4G、5G等)、…

SSM中PageHelper的使用步骤与com.github.pagehelper.PageHelper3系列与5系列的区别

SSM中PageHelper的使用步骤 一. 在pom.xml导入依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.2</version></dependency>二. 交给IOC管理 在SqlSessionFactory…

mysql修改数据库级别_设置数据库兼容级别的两种方法

兼容级别设置为 80 兼容级别设置为 90 影响的可能性对于 FROM 子句中的锁提示&#xff0c;WITH 关键字始终是可选的。但在一些例外情况中&#xff0c;仅当用 WITH 关键字指定表提示时&#xff0c;FROM 子句中才支持这些提示。有关详细信息&#xff0c;请参阅 FROM (Transact-SQ…

Github PageHelper 原理解析

任何服务对数据库的日常操作&#xff0c;都离不开增删改查。如果一次查询的纪录很多&#xff0c;那我们必须采用分页的方式。对于一个Springboot项目&#xff0c;访问和查询MySQL数据库&#xff0c;持久化框架可以使用MyBatis&#xff0c;分页工具可以使用github的 PageHelper。…