剖析Apple M1 GPU,第一部分

2021-01-09 07:07:30

苹果最新的Mac系列包括其内部的“ M1”片上系统,该系统具有定制GPU。这对于希望在我们的设备上运行Linux的Asahi Linux项目中的我们来说是一个问题,因为此自定义Apple GPU既没有公共文档也没有开源驱动程序。一些人推测它可能来自旧款iPhone中使用的PowerVR GPU,而另一些人则认为GPU是完全定制的。但是,当我们自己窥视内部时,谣言和猜测就不好玩了!

几周前,我购买了带有M1 GPU的Mac Mini作为开发目标,以研究指令集和命令流,以前所未有的水平了解GPU的体系结构,并最终加快Mesa驱动程序的开发用于硬件。今天,我已经达到了自己的第一个里程碑:我现在已经了解了足够的指令集,可以使用免费的开放源代码工具链(在GitHub此处发布)分解简单的着色器。

解码GPU的指令集和命令流的过程与我在Panfrost项目中对Mali GPU进行反向工程所使用的过程相似,该过程最初是由Lima,Freedreno和Nouveau自由软件驱动程序项目率先开发的。通常,对于Linux或Android驱动程序进行逆向工程,将编写一个小型包装库,以通过LD_PRELOAD注入到测试应用程序中,该应用程序挂接ioctl和mmap之类的关键系统调用,以便分析用户内核交互。发出“提交命令缓冲区”调用后,库可以转储所有(映射的)共享内存以进行脱机分析。

M1可以使用相同的整体过程,但是需要翻译一些macOSism。首先,在macOS上没有LD_PRELOAD;等效项是DYLD_INSERT_LIBRARIES,它具有一些额外的安全功能,可以轻松地将其关闭以达到我们的目的。其次,尽管标准的Linux / BSD系统调用确实存在于macOS上,但它们并不用于图形驱动程序。相反,苹果自己的IOKit框架用于内核和用户空间驱动程序,其关键入口点是IOConnectCallMethod(与ioctl类似)。这些差异很容易被掩盖,但是它们确实与标准Linux工具增加了一层距离。

更大的问题是将自己定位在IOKit世界中。由于Linux具有copyleft许可证,因此(合法)内核驱动程序是开源的,因此ioctl接口是公共的,尽管特定于供应商。受许可的macOS内核(XNU)不承担任何此类义务;内核接口是专有的且未记录。即使在包装完IOConnectCallMethod之后,也需要花些时间来确定三个关键调用:内存分配,命令缓冲区创建和命令缓冲区提交。包装分配和创建调用对于跟踪GPU可见内存(我们感兴趣的研究对象)是必不可少的,包装提交调用对于计时内存转储至关重要。

清除这些障碍之后,我们终于可以使用着色器二进制文件,即黑盒子。但是,从头到尾的过程是标准的:从最简单的片段或计算着色器开始,对输入源代码进行少量更改,然后比较输出二进制文件。重复此过程很繁琐,但是会很快揭示出关键结构,包括操作码编号。

自由软件反汇编器中记录的过程发现证实了GPU的许多特性:

一个,这是一个标量体系结构。与某些32位标量但16位矢量化的GPU不同,M1的GPU在所有位大小下都是标量。然而,Metal优化资源暗示16位算术应该大大加快,而且减少了寄存器使用量,从而导致更高的线程数(占用量)。这表明硬件是超标量的,与32位ALU相比,具有更多的16位ALU,从而使该部件比其他芯片更能受益于低精度图形着色器,同时消除了编译器的大量复杂性。

第二,这似乎可以处理硬件的调度,这在台式机GPU中很常见,但在嵌入式空间中则较少。这又使编译器更简单,但硬件更多。指令似乎具有最小的编码开销,这与其他体系结构不同,后者需要使用nop填充指令以适应高度受限的指令集。

三,支持各种修饰符。浮点ALU可以“免费”进行钳位(饱和),取反和绝对值修改器,这是常见的着色器体系结构特征。此外,大多数(全部?)指令都可以在目标和源上“免费”在16位和32位之间进行类型转换,从而使编译器在使用16位操作时更具攻击性,而不会冒转换风险间接费用。在整数方面,某些指令可免费使用各种按位补码和移位。这些都不是Apple设计所独有的,但值得一提。

最后,并非所有的ALU指令都具有相同的时序。避免使用像imad这样的指令来将两个整数相乘并加上第三个整数,而尽可能使用重复的iadd整数加法指令。这也暗示了超标量体系结构。像我日常工作一样,由软件计划的设计无法利用流水线长度上的差异,无意中降低了简单指令的速度,以适应复杂指令的速度。

从我以前使用GPU的经验来看,我继续期望在指令集中发现一些等待着编译的复杂性的eldritch恐怖。尽管上述工作目前仅覆盖指令集的一小部分表面积,但到目前为止,一切似乎都还不错。没有复杂的优化技巧,但要消除这种技巧,就可以创建一种精简而有效的设计,该设计可以一劳永逸。也许苹果的硬件工程师发现很难克服简单性。

las,没有开放源代码的用户空间驱动程序,着色器工具链就没什么用了。下一步:剖析命令流!

免责声明:这项工作是一项业余项目,基于公共信息进行。所表达的观点可能无法反映我雇主的观点。