Low-level Thinking in High-level Shading Languages
因为要反汇编shader代码,所以google了数学函数_sat的知识,发现了一些高级着色语言的优化相关的问题。Low-level Thinking in High-level Shading Languages,地址如下 http://www.luluathena.com/?p=1633
大意是汇编写shader,代码需要自己来优化。一直都是写HLSL这样的高级语言,编译器自动优化,却发现书写的代码会深深影响所生成的汇编效果。依赖编译器优化,总是那么不靠谱,所以懂点儿优化的程序员还是有市场的。
摘个例子1:
(x + 1.0f) * 0.5f所生成的汇编指令是两句,先add,再mul,很直观。而x*0.5f + 0.5f所生成的汇编指令只有一句,mad。这就是PC上编译器不会帮我们做的事情。由于浮点数的运算有误差,有时候编译器在为代码进行优化时,会由于修改了运算的顺序而导致INF和NAN(且不论编译器,甚至我们自己都会导致这种错误)。
考虑 x = 0.2f 时:
sqrt(0.1f * (0.2f - x)) 返回0
sqrt(0.02f - 0.1f * x) 返回 NaN //由于0.02f - 0.1f*0.2f 返回了一个极小的负值,导致开方出错
例子2:
- float AlphaThreshold(float alpha, float threshold, float blendRange)
- {
- float halfBlendRange = 0.5f*blendRange;
- threshold = threshold*(1.0f + blendRange) - halfBlendRange;
- float opacity = saturate( (alpha - threshold + halfBlendRange)/blendRange );
- return opacity;
- }
对应的汇编代码:
- mul r0.x, cb0[0].y, l(0.500000)
- add r0.y, cb0[0].y, l(1.000000)
- mad r0.x, cb0[0].x, r0.y, -r0.x
- add r0.x, -r0.x, v0.x
- mad r0.x, cb0[0].y, l(0.500000), r0.x
- div_sat o0.x, r0.x, cb0[0].y
而这段代码的精简版本:
- // scale = 1.0f / blendRange
- // offset = 1.0f - (threshold/blendRange + threshold)
- float AlphaThreshold(float alpha, float scale, float offset)
- {
- return saturate( alpha * scale + offset );
- }
对应的汇编就只有一条。
- mad_sat o0.x, v0.x, cb0[].x, cb0[].y
专注做产品的程序员不应该考虑太多底层优化的东西,而对于引擎程序员的要求,不论GPU还是CPU编程,都应该Low-level Thinking in High-level Languages
Low-level Thinking in High-level Shading Languages的更多相关文章
- 设计与实现的简单和经常使用的权限系统(五岁以下儿童):不维护节点的深度level,手工计算level,树形结构
以这种方式.和第三的类似介绍.所不同的是.深度未在数据库中存储节点level,添加和更改时间,护.而是,在程序中,实时去计算的. 至于后面的,依照level升序排序,再迭代全部的节点构造树,与第三篇 ...
- loadrunner / socket level data and wininet level data
s loadrunner录制脚本时,此网站证书无效/无法录制到脚本问题解决 http://www.51testing.com/html/64/497364-3569552.html lr录制后空白_l ...
- 简洁常用权限系统的设计与实现(五):不维护节点的深度level,手动计算level,构造树
这种方式,与第三篇中介绍的类似.不同的是,数据库中不存储节点的深度level,增加和修改时,也不用维护.而是,在程序中,实时去计算的. 至于后面的,按照level升序排序,再迭代所有的节点构造树,与 ...
- 简洁常用权限系统的设计与实现(六):不维护节点的深度level,手动计算level,构造树 (把一颗无序的树,变成有序的)
本篇介绍的方法,参考了网上的代码.在递归过程中,计算level,是受到了这种方法的启发. CSDN上有篇关于树的算法,目标是把一个无序的树,变成有序的. 我看了下代码,并运行了下,感觉是可行的. 我 ...
- [LeetCode] Binary Tree Level Order Traversal II 二叉树层序遍历之二
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...
- [LeetCode] Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...
- [LeetCode] Binary Tree Level Order Traversal 二叉树层序遍历
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- 《InsideUE4》-3-GamePlay架构(二)Level和World
UE4深入学习QQ群: 456247757 引言 上文谈到Actor和Component的关系,UE利用Actor的概念组成一片游戏对象森林,并利用Component组装扩展Actor的能力,让世界里 ...
- 【leetcode】Binary Tree Zigzag Level Order Traversal (middle)
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...
随机推荐
- codis须知
codis是豌豆荚team出的一个redis集群,和官方的集群区别的地方在于 基于proxy,官方是基于gossip codis所有的读写都通过proxy,对于前端业务是透明的 官方的是读写发现在某个 ...
- 根据现有表操作基于active record的model
指南上都是直接生成mode,然后db migrate来生成数据库,在现实场景中,很可能是反过来的 例如 测试表app_versions rails里面,建立model class AppVersion ...
- python3调用阿里云短信服务
#!/usr/bin/env python#-*- coding:utf-8 -*-#Author:lzd import uuidimport datetimeimport hmacimport ba ...
- Solr-DIH建立索引并执行简单初步的查询
我们将solr的安装目录设置为$SOLR_INSTALL, ./solr start,不使用任何原有的examples来进行,启动完成后,不存在任何的core,提示No cores availab ...
- Python开发一个堡垒机
项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功能只是堡垒 ...
- 关于eclipse open call hierarchy功能的一个细节
这个功能对应的快捷键是ctrl alt H,大家应该都很熟悉了.默认是查找这个方法的被调用堆栈.90%的人应该也是习惯这个默认的功能的,也基本无视它的另一个功能. 昨天重启eclipe之后,我的ecl ...
- C++Builder 也有StringBuilder
System::Sysutils::TStringBuilder *sb = new TStringBuilder; sb->Append("ww"); sb-& ...
- JAVA 非对称加密工具
import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; import java.securi ...
- Oracle的服务端_默认_启动的服务
- md5,原理待续
以前项目中copy出来的 import java.security.MessageDigest; public class MD5Util { /** * @todo MD5加码 生成32位md5码 ...