shader程序员需要注意的优化Tips
在写shader的时候,其实一些写法对于其执行影响非常大,而且由于gpu和cpu在架构上的不同,代码的优化思想也不一样,最近一直在写几个shader,为了性能问题,查阅了很多资料,把一些tips总结下来。
首先要树立几个思想:
1.gpu是SIMD的架构,即单指令多数据流架构,即在gpu上同时执行n个数据和执行1个数据的效率是一样的,我们要
尽量的把并行的计算搬到gpu上
2.gpu是以向量计算为基础设计的,也就是说在gpu上执行一个向量乘法和执行一个float的乘法的效率是一样的,
并不向cpu那样要多执行几次
3、通常,需要渲染的像素比顶点数多,而顶点数又比物体数多很多。所以如果可以,尽量将运算从PS移到VS,或直接通过script来设置某些固定值;
所以
1.尽量把一些计算合并成向量计算,记住一个向量计算和一个float计算那样快!
比如
float x,y;
x = x * a;
y = y * b;
不如写成 float2 v = float2(x,y);
v = v*float2(a,b);
因为前一种写法是两次乘法计算,而后一种只要1次
2.不要在gpu里面用分支或者条件判断这种语句,尽管大多数gpu 的shader支持这种语法,但是多数gpu里面的
这种控制语句涉及到一些同步等消耗的操作,其实大多数这种语句都可以用数值的方式替代。
比如 你想写
- float4 a;
- if(b > 1)
- {
- a.a=1;
- }
- else
- {
- a.a =0.5;
- }
可以改写成
- float4 a;
- float tmp = step(b,1);
- a = tmp * 0.5 + (1-tmp);
if else可以被step出来的0 或1的乘法代替又比如
- float4 a;
- if(b && c || d && e)
- {
- a.a = 1;
- }
- else
- {
- a.a = 0.5;
- }
可以写成
- float4 a;
- float tmp = step(1, (float)b*(float)c + float(d)*float(e));
- a = tmp + (1-tmp) * 0.5;
&& 我们用转换到float后的乘法代替,||可以被判断加法step 1代替
而这种操作,尤其是shader内置的函数比条件判断和分支的效率要高很多,别忘了,GPU纯粹是为了计算的,而不是做判断
3.尽量使用shader为我们提供的内置函数,这些内置的函数比我们想象的要快很多,往往应用了某些gpu的特殊特性。
比如要比较a和b谁大用max(a,b),还有例如上面反复用的step,虽然你可以写用(float)(a>=1)来替换step(1,a),
但是这还是没有内置函数更快的,包括常用的saturate()把一个数归到0-1,总之一句话,如果能用一个内置函数替换
你的某些代码,就尽量替换。而且这些内置函数基本上都是支持对向量操作的,所以如果用step(a,fixed3(1,2,3))其
实只是一条指令,但是却可以同时返回用a同1 2 3分别比较的结果。
4.使用swizzle是非常快的,例float4 a = float4(1,1,1,1),用a.wz = float2(2,3)要比 a.w=3; a.z=2要高效很多
5.浮点数精度相关:
float:最高精度,通常32位
half:中等精度,通常16位,-60000到60000,
fixed:最低精度,通常11位,-2.0到2.0,1/256的精度。
尽量使用低精度。对于color和unit length vectors,使用fixed,其他情况,根据取值范围尽量使用half,实在不够则使用float。
在移动平台,关键是在fragment shader中尽可能多的使用低精度数据。另外,对于多数移动GPU,在低精度和高精度之间转换是非常耗的,在fixed上做swizzle操作也是很费事的。
6.Alpha Test
Alpha test和clip()函数,在不同平台有不同的性能开销。
通常使用它来cull那些完全透明的像素。
但是,在ios和一些android上使用的PowerVR GPUs上面,alpha test非常的昂贵。
7、Color Mask
在移动设备上,Color Mask也是非常昂贵的,所以尽量别使用它,除非真的是需要。
8、在使用Surface Shader时,可以通过一些指令让shader优化很多。
通常情况下,Surface shader的很多默认选项都是开启的,以适应大多数情况,但是很多时候,你可以关闭其中的一些选项,从而让你的shader运行的更快:
(1) approxview 对于使用了view direction的shader,该选项会让view dir的normalize操作per-vertex进行,而不是per-pixel。这个优化通常效果明显。
(2) halfasview 可以让Specular shader变得快一些,使用一个介于光照方向和观察方向之间的half vector来代替真正的观察方向viewDir来计算光照函数。
(3) noforwardadd Forward Render时,完全只支持一盏方向光的per-pixel渲染,其余的光照全部按照per-vertex或SH渲染。这样可以确保shader在一个pass里渲染完成。
(4) noambient 禁掉ambient lighting和SH lighting,可以让shader快一点儿。
shader程序员需要注意的优化Tips的更多相关文章
- 面向.Net程序员的后端性能优化实战
最近2个月没做什么新项目 完全是对于旧的系统进行性能优化 避免超时 死锁 数据处理能力不够等常见的性能问题 这里不从架构方面出发 毕竟动大手脚成本比较高 那么我们以实例为前提 从细节开始 优化角度 一 ...
- C++程序员容易走入性能优化误区!对此你怎么看呢?
有些C++ 程序员,特别是只写C++ 没有写过 Python/PHP 等慢语言的程序员,容易对性能有心智负担,就像着了魔一样,每写3 行代码必有一行代码因为性能考虑而优化使得代码变形(复杂而晦涩). ...
- 程序员修炼之道中所有tips总结
1 关心你的技艺 如果你不在乎能否漂亮地开发出软件,你又为何要耗费生命去开发软件呢? 2 思考!你的工作 关掉自动驾驶仪,接管操作.不断地批评和评估你的工作. 3 ...
- 程序员必备SQL语句优化技巧
1.任何地方都不要使用 select * from t ,用具体的字段列表代替"*",不要返回用不到的任何字段. 2.尽量使用数字型字段,字符型会降低查询和连接的性能,并会增加存储 ...
- Oracle学习总结(8)—— 面向程序员的数据库访问性能优化法则
特别说明: 1. 本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2. 本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也 ...
- PHP程序员福利“看免费直播,学MySQL索引优化”
六星教育了解到,MySQL是目前所知PHP最流行的关系型数据库管理系统之一,它将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.之所以它会成为主流使用数据库,这 ...
- fir.im Weekly - 每个程序员都应当拥有的技能树
本周收集了一些优秀的 iOS & Android 开发资源和程序员 IT 技能拓展的 Tips. 知道创宇研发技能表 v3.0 作为程序员可能都听说过[知道创宇],他们是一家黑客文化浓厚的安全 ...
- 对于长沙互联网发展,一个外来两年Java程序员的所见所感所愿
惟楚有材,于斯为盛 本文有感于2019长沙互联网求职招聘大会,内容比较多,但都是我自己的一些所见.所感和所愿. 2019年3月的最后一天,参加2019长沙互联网求职招聘大会,看到了很多的招聘企业,也看 ...
- PHP对程序员的要求更高
我这个文章标题可不是和大家开玩笑的哦 首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译.. 为此, 也 ...
随机推荐
- cookie和session(一)
先来谈谈我对session和cookie的理解,事实上,只要你去面试web开发,面试官十有八九会问这个问题. cookie和session经常被放在一起问,其实在我看来这两个东西完全是两个不一样的. ...
- MPSOC之5——开发流程BOOT.BIN
需要把若干文件打成大包,烧写到flash或者sd卡中,才能启动运行. 1.petalinux打包 petalinux-packet打包时,需要petalinux的工程,限制太死了,不用. 2 wind ...
- mysql新建数据库,并设置charset为utf8,使用utf8_general_ci字符集校验结果
一. 实现功能 有时候在linux服务器端, 会在mysql命令行中, 创建数据库, 今天讲一下怎么在创建数据库时, 把charset设置为utf8,collate设置为utf8_general_ci ...
- Struts配置详解
一.Stuts的元素 1 web.xml 任何一个web应用程序都是基于请求响应模式进行构建的,所以无论采用哪种MVC框架,都离不开web.xml文件的配置.换句话说,web.xml并不是Struts ...
- DotNetCasClient 如何获取Cas服务器返回的attributes中的数据
最近开始接触做与其它认证系统的集成,其中有个是与某学校的CAS服务器集成.cas服务器认证成功后返回的数据格式如下: 其中红色部分是我需要取出来用于识别用户身份的数据. 一开始,我根据网上的教程,引用 ...
- 7.python常用模块
1.time 常用表示时间方式: 时间戳,格式化的时间字符串,元组(struct_time) UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时 ...
- Eclipse 问题整理
新建servlet报错,提示找不到javax.servlet包 解决的方法:把tomcat安装包里的lib目录下的servlet-api.jar拷贝一份到工程文件夹下的web目录下的WEB-INF目录 ...
- 二叉树Bynary_Tree(2):二叉树的递归遍历
7/18/2017 正在码,理解完就写博 7/21/2017 终于码完,借助链表实现的队列撸一个二叉树对于我来说有难度,撸了两天没有成果,我最后选用的是数组实现的循环队列去撸一个二叉树 正文如下: 以 ...
- ArcGIS Runtime SDK是什么?
如上图,Runtime SDK是什么东西?居然还有安卓.苹果手机.Mac.QT的版本? 是不是意味着ArcGIS的编辑数据和空间分析可以通过编程的方法在每个平台上满地跑了? 答案是:是,也不是. 1. ...
- grep 与 find 简单命令
在使用linux的时候,经常会用到查找文件或者查找文本,下面介绍两个命令. grep 使用方法: // 在当前目录下递归查找class字符串 grep "string" -r . ...