新一代GPU针对不同精度
有不同算力或优化,就业界开发多年经验,应该是软硬件必走趋势。
虽然PC用的北极星架构没有双倍fp16运算能力,但它也已经实作"fp16暂存器"。
让gpu有限的register用在刀口上,提升效率。
(以前硬件很笨,要fp16只能存成fp32,占2倍暂存器,不够用就开始影响效能)
如果全用fp32写shader,不代表追求高品质
只代表你笨,白耗费宝贵暂存器可能影响效率。连神仙写的compiler,都救不了无谓的浪
费。
如果讲全用fp16冲效能而影响画质,
那是脑补,哪家TA写code时不能
视精度需求而使用?
优化已经通行很久,只是以前你不知道,
而且以前优化能有多少效果因平台而异。
但由于绘图算法是能跨平台的。
大部分开发商也不是这辈子只做一平台。
所以在撰写时是根据泛用优化原则,
反正故意用全精度也不会比较好写,
之后开发其他平台时等于找自己麻烦。
至于能否因为GPU支援fp16,
游戏绘图就跑2倍快?
我是不认为,因为没人会全用fp16.
但这其实不重要,反正确实有帮助。
所以GPU是一定往这方向发展,
就算不是加速成200%,谁会拒绝更有效率?
例如你从domain shader/vertex传入的
各种插补向量值(用于后续),因插补而长度改变。
必须要在PixelShader正规化(长度归为一)
明知其向量xyzw范围不可能超过half的范围,(因为你在VertexShader早以对向量正规化,
已知它范围在哪,不可能有超出。)
硬要用fp32来算normalize不会让这颗pixel比较"帅"。
拉高无谓的精度,也对画质0影响0加分。
所以早期nvidia有个fp16 normalize unit
专门加速这种运算,后来新架构拔掉。
但拔掉不是因为精度,而是那种固定运算单位,不能泛用跑其他指令。随着shader复杂化
,该指令运用比例下滑,留那种
没泛用性的特殊单位,反而B>Z.
占用电晶体却常常闲置。
通常优化原则ꀨ各家引擎文件应都有说)
世界座标的顶点positions 通常得用float
(因为"世界"范围太广,显然不能低精度)
贴图座标texture coordinates 最保险能float ,但很多状况用half甚至fixed也行。
因为uv mapping范围是事先就决定。
你会知道这shader用到的范围没超过。
至于其他向量或color全都用half就很足够。因为向量长度是通常都是1...不是1你也得让
它变成1....
早年PC开发较不在乎有没好好指定精度,是因以前GPU硬件很笨。
(省电晶体简化设计,冲效能只靠拼sp数量)
比较旧的技术资料甚至告诉你,
不管怎么设置速度与占用资源都不变。
因为早期PC显核,是不管shader用float或half,内部强制全用fp32运算,并且全用fp32暂
存...
但几年前开始慢慢不是这样了。
似乎从硬件资源更紧的手持显核开始带动,发现好用而延伸到PC显核,会导致
shader演算硬件稍微变复杂,但有效率。
部分原因可能是半导体制程的进化速度
遇到瓶颈变缓,PC暴力堆积sp的速度变
慢,开始必须更在意用有限资源提升效率。
GPU硬件也不一定要完整支援到翻倍fp16算力,才能有意义。
即使只是GPU硬件懂得运用fp16来暂存,
就能减少register pressure.
.....效率就是生命。
现在主流引擎下的shader多是能跨平台泛用的。只是你要不要功能全开。
同一个shader运用在不同平台或游戏要省效能,通常是减少运算复杂度,关掉不必要的功
能(特效).
精度本身不用刻意改变。因为你本来就照不影响画质的优化原则去设精度。
不能改低的再怎样也不能改(画面会出错)
Shader都是Just in time compiler
即时改即时看,就马上看到修改效果品质。
出错你眼睛正常不会不知道。
例如uv贴图座标. ,超出范围不是品质变化,而是贴图完全出错出包,像是大bug....