苹果Arm芯片适配开发 (Apple Silicon)

1,218 阅读12分钟

文章目录

苹果Arm芯片适配开发 (Apple Silicon)

Apple Silicon

构建原生运行在Apple silicon上的应用程序、库、框架、插件和其他可执行代码。当您在Apple框架和技术之上构建可执行文件时,您可能需要采取的唯一重要步骤是为arm64架构重新编译代码。如果您依赖于特定硬件的细节,或者假设底层特性,那么根据需要修改您的代码以支持Apple silicon。 

Apple Silicon
要想在Apple silicon上获得最佳性能,有时需要调整使用硬件资源的方式。尽可能使用高级技术来减少对硬件的依赖。例如,使用Grand Central Dispatch而不是自己创建和管理线程。在Apple silicon上测试您的更改,以验证您的代码的行为是否最佳。

1. 将macOS应用程序移植到苹果芯片上 

创建一个macOS应用程序的版本,可以在基于苹果硅和英特尔的Mac电脑上运行。 

通过创建通用二进制文件并修改代码以处理架构差异,将现有macOS应用移植到Apple silicon。一个通用的二进制文件看起来和一个普通的应用程序没有什么不同,但是它的可执行文件包含编译代码的两个版本。一个版本在苹果芯片上运行,另一个版本在基于英特尔芯片的Mac电脑上运行。在运行时,系统会自动选择在当前平台上运行的版本。

两个版本

要构建通用二进制文件,您需要Xcode 12或更高版本,该版本将arm64添加到macOS二进制文件的标准构建体系结构列表中。当你打开你的项目并做一个干净的构建时,如果你的项目使用标准架构,Xcode会自动创建一个通用的二进制文件。如果您使用定制的makefile或构建脚本,请将arm64体系结构添加到构建系统中。 

创建通用二进制文件后,在两个体系结构上测试它,并确定是否需要进行其他更改。macOS框架保护应用程序不受平台之间架构差异的影响,但有些差异可能仍然需要您更改代码。此外,架构上的差异可能会影响应用程序的性能,需要进行进一步的更改。

Apple silicon上,为x86_64架构构建的应用程序在Rosetta翻译环境下运行。更多信息请参考:About the Rosetta Translation Environment.
要了解如何构建通用二进制文件,请参见构建通用macOS二进制文件

1.1 创建一个移植计划 

在移植过程的早期,确定您将用于构建和测试代码的工作流。Xcode可以在所有的Mac电脑上运行,因此可以在基于苹果硅芯片或英特尔芯片的Mac电脑上构建代码,并在那里进行初始测试。但是,始终在这两种计算机类型上测试、调优和验证您的代码,以发现特定于该体系结构的问题。 

开发流程

除了工作流程计划之外,还要确定在移植过程中需要研究的潜在领域。对于arm64的移植工作取决于您对特定硬件特性的依赖程度。如果您主要依赖Apple框架和技术,那么您的移植工作可能会很小。如果您专门针对x86_64体系结构和硬件功能调整了代码,那么移植到arm64可能需要额外的工作。 

要开始调查,请记下任何执行以下操作的代 码:

  • 与您不拥有的第三方库交互。

  • 与内核或硬件交互。

  • 依赖于特定的GPU行为。

  • 包含汇编指令。

  • 管理线程或优化你的应用程序的多线程行为。

  • 包含硬件特定的假设或性能优化。

上面的列表并不详尽,但它为您的调查提供了一个起点。硬件和架构上的差异可能会给您的代码带来bug或性能问题。尽早发现潜在的问题领域将为您以后节省时间。 

始终拥有一个定义良好的测试计划,理想情况下拥有一组可以在构建时运行的自动化测试套件。除了测试代码的正确性,还可以收集应用程序的性能指标。检查你的应用程序的内存使用情况,并测量它在苹果硅和基于英特尔的Mac电脑上执行特定任务所需的时间。利用这些信息来确定需要调查的其他领域。 

1.2 获取链接库的通用版本

如果您的项目依赖于任何第三方库,请联系原始供应商,要求他们为您提供这些库的通用版本。在同一进程中运行的所有代码必须支持相同的体系结构。如果没有所有链接库的通用版本,就无法生成二进制文件的通用版本。如果一个或多个库不是通用的,链接器会报告错误。

获取第三方库通用版本

要了解如何创建自己的通用二进制文件,请参见构建通用macOS二进制文件。

 1.3 将插件更新为通用二进制文件 

一个通用插件可以在任何Mac电脑上运行。如果您的应用程序支持插件模型,请创建您管理的插件的通用版本。如果您的公司允许外部开发人员贡献插件,请鼓励这些开发人员创建他们的插件的通用版本。 

如果应用程序直接将这些插件加载到进程空间,通用插件是必不可少的。在相同进程中运行的代码必须支持相同的体系结构。如果您的应用程序试图加载一个具有不兼容架构的插件,系统在加载时报告一个错误。

通用性插件

使用XPC服务运行进程外的插件可能使用与应用程序本身不同的架构运行。为了给开发人员更新插件的时间,提供两个非通用的XPC服务—一个运行arm64插件,另一个运行x86_64插件。单个XPC服务可以管理本机插件或转换插件,但不能同时管理两者。在创建服务时,为每个服务提供唯一的bundle标识符,以便它们可以同时运行。 

有关如何使用XPC与进程外插件通信的信息,请参见XPC

1.4 寻址架构差异 

除了处理器和图形硬件的大规模变化,苹果硅芯片和基于英特尔的Mac电脑之间存在着微妙的架构差异。在移植过程中,审计您的代码以确定任何潜在架构问题的修复。例如,查找代码依赖于特定硬件特性或配置的位置。 

下面的列表列出了苹果硅芯片和基于英特尔芯片的Mac电脑之间几个已知的架构差异。更新代码,依赖于任何以 下:

  • 虚拟内存页面大小

  • 高速缓存线路尺寸

  • 可变的函数

  • 同时可写和可执行的内存

  • 即时编译器

  • 实时线程

  • 显式线程优先级

  • 特定于硬件的细节

  • 汇编语言指令或内建函数

  • 单位向量指令

  • c++ ABI的细节

Apple silicon和基于intel的Mac计算机都使用小端格式的数据,所以您不需要在代码中进行end转换。但是,继续尽量减少在创建的自定义数据格式中进行末端转换的需要。

有关架构差异的其他信息,请参见在macOS代码中处理架构差异。  

1.5 更新GPU-Specific代码 

苹果芯上的Metal支持基于英特尔的Mac电脑和iOS设备的功能。如果您的应用程序采用了只有在基于intel的Mac电脑上才能找到的Metal特性,那么请考虑在您的arm64代码中也采用ios特有的特性。采用这些特性可以提高许多应用程序的性能。 

 如果您的应用程序使用Metal, OpenGL,或OpenCL,请注意以下差 异:

  • 苹果芯片上的GPUCPU共享内存。

  • OpenGL是不推荐的,但在苹果芯上是可用的。

  • OpenCL是不推荐的,但在针对GPU时,它是可用的。OpenCL CPU设备对arm64应用程序不可用。

有关如何更新图形代码的信息,请参见将Metal代码移植到Apple Silicon

1.6 更新驱动,系统扩展,内核扩展

在将代码移植到macOS 11时,请注意与内核交互的代码的以下要求:

  • 使用DriverKit实现硬件驱动程序。macOS 11要求你使用一个驱动套件扩展,当支持是可用的。大多数驱动程序类型现在都支持DriverKit,只有少数仍然需要创建内核扩展。

  • 内核扩展必须支持本机体系结构。内核扩展在内核中运行,并且内核始终作为本机进程运行。不能使用Rosetta翻译运行内核扩展。

  • 内核扩展的安装和卸载需要重新启动。当您安装内核扩展时,系统直到重新启动后才加载扩展。

有关内核扩展和驱动程序更改的更多信息,请参见实现驱动程序、系统扩展和kext

1.7 远离特定的技术

macOS包括一些目前不推荐或不鼓励积极开发的技术。如果您的应用程序使用下列技术之一,迁移到适当的替代尽快:

Apple silicon 仍然提供对上述技术的支持,你可以继续在macOS 11中使用它们。但是,这种支持可能会在macOS的未来版本中删除,所以建议迁移到较新的技术。 

1.8 调试和测试代码 

Apple silicon支持所有在基于intel的Mac电脑上发现的调试和测试工具。使用Xcode IDE来设置和监控断点,以及监控应用程序其他方面的行为。在命令行中使用lldb在Xcode接口之外执行类似的任务。  

有关如何调试和测试代码的更多信息,请参见Xcode。 

1.9 调整你的应用程序的性能 

苹果硅可以运行基于英特尔的Mac电脑上的所有性能工具。使用工具和其他性能工具为你的应用收集不同类型的指标,包括内存使用,速度,能源使用等信息。您还可以使用命令行工具(如leaks、heap、top、fs_usage、sc_usage、vm_stat、otool、sample、malloc_history和vmmap)来识别潜在的性能问题。 

arm64和x86_64之间的架构差异意味着,在一个系统上运行良好的技术可能在另一个系统上运行不好。例如:

  • 不要假设独立GPU意味着更好的性能。苹果处理器的集成GPU为高性能图形任务进行了优化。请参阅将您的Metal代码移植到苹果芯

  • 不要假设所有的处理器核心都是相同的。Apple silicon上的处理器混合了性能核心(p -core)效率核心(e -core),它们执行具有不同性能特征的任务。使用**服务质量(QoS)**类来帮助系统在正确的核心类型上调度任务。

在移植过程中,测量你的应用程序在苹果芯和基于英特尔的Mac电脑上的性能,并调查任何差异。在一个平台上运行时间较长的任务可能需要额外的调优。

有关调优通用二进制文件的具体技巧,请参见为Apple Silicon调优您的代码性能

构建一个通用macOS二进制文件

解决macOS代码中的体系结构差异

将您的音频代码移植到苹果芯片

将即时编译器移植到Apple Silicon

将您的Metal代码移植到Apple Silicon

为苹果芯片调优您的代码性能

关于Rosetta翻译环境

在macOS上运行iOS应用程序

实现驱动程序、系统扩展和kext

安装自定义内核扩展

调试自定义内核扩展

有想要的面试资料或者其他资料可以去看我主页加我,欢迎咨询!

文章接下来还会持续更新,你也可以私信我及时获取面试相关资料。如果你有什么意见和建议欢迎给我留言。
请iOS的小伙伴关注 !喜欢的话给一个赞吧!谢谢!谢谢!谢谢!

原文链接:blog.csdn.net/kyl28288954…