之前测过Mesa 26.2.1版本( https://vkdb.niconiconi.us/gpus/29 )相比之前有一定的性能提升,但是计算类型还是只支持fp32和int32,于是开始研究怎么给他加fp16 int16 int8的支持另外提升一点性能
设备使用 SpacemiT K3 Pico-ITX 上的 PowerVR BXM-4-64 MC1,BVNC 为 36.56.104.183。测试以 Mesa 26.3.0-devel(4f00b70da3)为基础。
首先是支持 FP16、INT16、INT8
主要做法是在 NIR 到 PCO 的编译路径中复用已实现的 32 位运算路径,因为img那边并没有开发 f16sop 的路径,目前仍是一堆TODO,要是有 f16sop 性能还能再上一层楼。
核心要点大概如下:
nir_lower_mem_access_bit_sizes 将窄类型的 buffer 访问转换为 32 位访存,再提取或合并所需的 16 位数据;部分非对齐窄写入可能走原子操作。
nir_lower_bit_size 将低于 32 位的算术提升至 32 位,在转换和存储边界收窄。PCO 入口另设最终处理步骤,覆盖内部 shader 路径。
开放 shaderFloat16、shaderInt16、shaderInt8、storageBuffer16BitAccess,以及 VK_KHR_16bit_storage 和 VK_KHR_shader_float16_int8。
这样的话就实现了在fp32的路径上实现了较低精度
在做int8的时候还看了这个 https://docs.imgtec.com/reference-manuals/powervr-instruction-set-reference/html/topics/integer-instructions/IMAD8.html
但是发现并不符合vulkan对于int8的计算定义
这个阶段做完的vkpeak成绩为:
FP16 scalar 8.85 GFLOPS
FP16 vec4 6.49 GFLOPS
INT16 scalar 3.26 GIOPS
INT16 vec4 3.80 GIOPS
INT8 dot 4.29 GIOPS
接下来是性能优化:
首先是启用了 NIR 的 has_imad32 ,因为 PCO 现在已经可以翻译 imad,但此前未向 NIR 声明该能力,整数乘加链因而保留为分开的乘法和加法。
然后是优化有符号饱和加法的降级,这一点是在int8上面做的,因为上面做出来的int8性能和闭源驱动有很大差距,用溢出判定表达式处理 iadd_sat,减少展开后的指令组;单 shader 总组数 204 → 159。
这一点的简易case:
sum = a + b
overflow = ((a ^ sum) & (b ^ sum)) < 0
limit = (a >> (bits - 1)) ^ ((1 << (bits - 1)) - 1)
result = overflow ? limit : sum
大概就是这样,不过还没有做过Vulkan CTS不确定会带来什么负面影响,倒是性能确实是好不少部分项目比闭源驱动也要更好
| vkpeak 项目 | 单位 | Mesa 26.2.1 | 优化后 Mesa 26.3-devel | 提升/降低幅度 | 闭源 IMG DDK 24.2@6603887 | 提升/降低幅度 |
|---|---|---|---|---|---|---|
| FP32 scalar | GFLOPS | 8.85 | 8.85 | 0.0% | 11.06 | −20.0% |
| FP32 vec4 | GFLOPS | 6.04 | 6.04 | 0.0% | 2.34 | +158.1% |
| FP16 scalar | GFLOPS | 0 | 8.85 | — | 10.07 | −12.1% |
| FP16 vec4 | GFLOPS | 0 | 6.49 | — | 5.40 | +20.2% |
| INT32 scalar | GIOPS | 2.53 | 8.13 | +221.3% | 7.41 | +9.7% |
| INT32 vec4 | GIOPS | 3.72 | 6.05 | +62.6% | 0.79 | +665.8% |
| INT16 scalar | GIOPS | 0 | 6.66 | — | 7.17 | −7.1% |
| INT16 vec4 | GIOPS | 0 | 5.94 | — | 0.79 | +651.9% |
| INT8 dot product | GIOPS | 0 | 6.45 | — | 49.42 | −86.9% |
| INT64 scalar | GIOPS | 0 | 0 | — | 3.20 | — |
| INT64 vec4 | GIOPS | 0 | 0 | — | 0.18 | — |
| Copy H2H | GB/s | 6.39 | 6.82 | +6.7% | 6.39 | +6.7% |
| Copy H2D | GB/s | 0.54 | 0.54 | 0.0% | 0.53 | +1.9% |
| Copy D2H | GB/s | 0.91 | 0.91 | 0.0% | 0.92 | −1.1% |
| Copy D2D | GB/s | 4.08 | 4.17 | +2.2% | 5.95 | −29.9% |
mesa pr: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/44801
版权属于:Kiritake Kumi (Niconeiko) ,本文所引用的第三方材料版权归属为:第三方材料的所有者
本文链接:https://blog.mxpkx.com/index.php/archives/346/
除特殊标注以及**影像内容**外,均使用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)协议 ,影像内容请务必联系确认是否可以转载使用