Zink 是基于 Vulkan 的 OpenGL 实现,Valve 公司 Linux 图形驱动程序团队的 Mike Blumenkrantz 最近在研究 Zink 过度使用内存问题的来源。他已经为 Mesa 23.1 提交了一个 Zink 驱动内存优化补丁,这个改动使 Mesa Zink 驱动程序的内存使用率在大多数游戏中减少一半,但不会对性能产生任何负面影响。
背景
OpenGL 的游戏很多都是 x86 二进制文件,它们在 32 位进程中运行,而 32 位地址空间意味着可寻址内存有 4GB 限制,这个限制包括游戏的可寻址内存(例如,游戏的内部 malloc 调用)以及驱动程序的可寻址内存(例如,所有 GPU 映射内存),一旦内存占用临界或者超过该限制,应用就会崩溃。
之前 Mesa RADV 驱动程序就出现过内存问题,在打开 Dota 2 时,RADV 驱动程序占用了 3GB 主机内存。其中大部分内存占用都来自于内存着色器 IR,最后通过序列化内存中的着色器,节省了 85% 的内存,解决了内存占用异常问题。
Mesa Zink 驱动程序的内存使用和 RADV 驱动的问题有点相似。、Mike 在一篇博文中讲述了自己的内存优化过程,这次作为实验的游戏是古墓丽影三,最初打开游戏时内存占用 2.4 G,而且几乎全部由驱动程序分配:
第一步是着手序列化所有 NIR 着色器(NIR 是一种中间表示 (IR),专为满足 Mesa 中图形驱动程序的需求而设计。)。因为克隆 NIR 着色器会消耗过多的 RAM,对于创建大量图形的游戏来说,这很容易导致内存爆炸。序列化 NIR 比对象形式的 NIR 更紧凑,内存占用量小了一个数量级,使用序列化的 NIR 着色器对内存问题有很大帮助。第二步是压缩链接着色器时发生的 NIR 副本。最后将 Mesa RADV 的修复程序应用到 Mesa Zink 中。
最终将古墓丽影 3 的内存使用量降到 482.7 MB,减少了 79.9% 。