GPU供应商建议减少着色器中使用的VGPR(矢量通用寄存器)的数量,因为它们的数量有限,过度使用会降低GPU占用率。所以我编译了一个发出白色的简单片段着色器,并使用Radeon GPU Analyzer(RGA)检查了VGPR的使用情况
void main(void)
{
gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
}
令我惊讶的是,它发出了一个相当大的着色器
1 | 1 | ^ | label_basic_block_1: v_mov_b32 v0, 0
2 | 2 | :^ | v_mov_b32 v1, 1.0
3 | 3 | v:^ | v_cvt_pkrtz_f16_f32 v2, v0, v0
4 | 4 | vv:^ | v_cvt_pkrtz_f16_f32 v3, v0, v1
5 | 4 | ::vv | exp mrt7, v2, v2, v3, v3
6 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v5, v0, v0
7 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v6, v0, v1
8 | 4 | :: vv | exp mrt6, v5, v5, v6, v6
9 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v8, v0, v0
10 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v9, v0, v1
11 | 4 | :: vv | exp mrt5, v8, v8, v9, v9
12 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v11, v0, v0
13 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v12, v0, v1
14 | 4 | :: vv | exp mrt4, v11, v11, v12, v12
15 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v14, v0, v0
16 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v15, v0, v1
17 | 4 | :: vv | exp mrt3, v14, v14, v15, v15
18 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v17, v0, v0
19 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v18, v0, v1
20 | 4 | :: vv | exp mrt2, v17, v17, v18, v18
21 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v20, v0, v0
22 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v21, v0, v1
23 | 4 | :: vv | exp mrt1, v20, v20, v21, v21
24 | 3 | v: ^ | v_cvt_pkrtz_f16_f32 v23, v0, v0
25 | 4 | vv :^ | v_cvt_pkrtz_f16_f32 v24, v0, v1
26 | 2 | vv | exp mrt0, v23, v23, v24, v24
27 | 0 | | s_endpgm
Maximum # VGPR used 4, # VGPR allocated: 25
仔细观察会显示' exp mrt0',' exp mrt1' ......很明显,所有八个可用的MRT轨迹都被写入。所以我稍微更改了着色器
void main(void)
{
gl_FragData[0] = vec4( 0.0, 0.0, 0.0, 1.0 );
}
并且寄存器分配从 25降至3 (!),指令数从 27降至6
1 | 1 | ^ | label_basic_block_1: v_mov_b32 v0, 0
2 | 2 | :^ | v_mov_b32 v1, 1.0
3 | 3 | v:^ | v_cvt_pkrtz_f16_f32 v2, v0, v0
4 | 3 | xv: | v_cvt_pkrtz_f16_f32 v0, v0, v1
5 | 2 | v v | exp mrt0, v2, v2, v0, v0
6 | 0 | | s_endpgm
Maximum # VGPR used 3, # VGPR allocated: 3
我现在有点困惑。在这种情况下我不需要MRT,但无论如何,
为什么写入7 MRT(mrt1..mrt7)使用不少于22个VGPR?为什么我们不能从一个寄存器写?
仅仅是为了感兴趣,这次MRT写作是否并行完成,或者我们真的花了20多条指令呢?
如果我只写入gl_FragData [0] / MRT0,着色器的执行速度是否会受益于降低的VGPR使用率?如果不是这种情况,在VGPR使用率下降的情况下是否会受益40分配给18个分配的VGPR?
(是的,我知道在最新的GLSL版本中不推荐使用gl_FragDataXY,但我仍然想编写可以在旧卡上运行的代码。)
答案 0 :(得分:0)
为什么写入7 MRT(mrt1..mrt7)使用不少于22个VGPR?为什么我们不能从一个寄存器写?
" can&#t; t"并且"没有"#34;你没有考虑到。事实是它是2017年:gl_FragColor
是预定义的输出,已经从GLSL中移除了近十年。 AMD没有理由优化此值的使用。
因此虽然它可能做得更好,但编译器不会做得更好。
如果我只写入gl_FragData [0] / MRT0,着色器的执行速度是否会受益于VGPR的使用减少?
优化并不那么简单。没有办法确定,特别是在真实世界的着色器中,写入gl_FragColor
的额外VGPR可能无关紧要,因为它可以重用其他代码分配的VGPR。