苹果公司于 2020 年末推出了三款搭载有 Apple M1 芯片(又称 Apple silicon)的 Mac 电脑。这种由 Apple 研发的处理器芯片与以往 Mac 搭载的 Intel 处理器存在处理器架构上的差异。Intel 推出的桌面处理器采用 X86 架构,使用 x86_64 指令集,而 Apple M1 芯片基于 ARM 架构,使用 arm64 指令集。指令集的差异使得为 x86_64 指令集编译的程序无法直接在基于 Apple M1 芯片上运行。
本文介绍了 Apple 公司于 macOS 中引入的一项被称为 Rosetta 2 的技术,这项技术能以一种变通的方式将为 Intel 处理器编译的程序运行于 Apple M1 芯片上。
Rosetta 2 是什么
Rosetta 2 是苹果于 macOS 上推出的指令集转译程序,它允许用户在 Apple silicon 上运行包含 x86_64
指令集的程序。由于为 Mac 编写的大多数应用程序通常为 Intel 架构的处理器设计,通过 Rosetta 2 这项技术,能够使用户在开发者未提供面向 Apple silicon 准备的程序时,变通地将这些程序运行于 Mac 中。
Apple 表示,Rosetta 2 并不是替代应用程序原生版本的方案,而只是为开发者准备调整到通用应用程序的过渡方案。
有一款可以运行于 Mac 上的生物学类软件亦名为 Rosetta,请读者不要将此混淆
对于用户来说,Rosetta 几乎是透明的(对用户无感知)。每当用户运行为 Intel 处理器构建的应用程序时,Rosetta 2 都会在后台运行。Rosetta 会自动转译 App 以便与 Apple 芯片搭配使用。当转译过程完成后,操作系统将为用户运行转译后的应用程序。转译程序的过程需要一定的时间,因此用户可能感觉需转译的应用程序启动速度比往常略慢。
通用应用
Apple 于 macOS Big Sur 中引入了名为“通用应用”的概念。这种类型的应用中同时包含为 Intel 处理器以及 Apple 处理器构建的程序。而搭载 Apple M1 芯片的 Mac 电脑则会在同时存在 arm64
与 x86_64
指令集的程序时优先选择 arm64
指令集版本的程序。
出于避免未知缺陷的考虑,Apple 为通用应用程序提供了强制使用 Rosetta 而使用 x86_64 指令集的相应选项。在应用程序列表中,选择“显示简介”,并查看标有“种类”字样的信息:
- 应用程序 (Intel) 表示 App 仅支持 Intel 处理器,并且需要 Rosetta 才能在任何搭载 Apple 芯片的 Mac 上运行
- 应用程序(通用)表示 App 同时支持 Apple 芯片和 Intel 处理器,并且在默认情况下使用 Apple 芯片
若要对于通用应用程序优先使用 x86_64
指令集的版本,则应将“使用 Rosetta 打开”选项勾选,以使这些应用程序能够使用未被 arm64
架构支持的其他拓展功能。
Rosetta 2 转译的性能
自搭载 Apple M1 芯片的 Mac 设备上市以来,许多用户关注在 M1 芯片上运行 Intel 应用程序的速度问题。Apple 公司声称,在大多数情况下,使用 Rosetta 的 App 的性能不会出现任何差异。互联网中的一些实际测试表明通过 Rosetta 2 转译的应用程序的性能约为原生应用的 80% 左右。
哪些程序不能被 Rosetta 转译
Rosetta 能够转译绝大多数为 Intel 处理器构建的应用程序,其中包括含有即时编译(just-in-time,JIT)技术的编译器程序。然而,Rosetta 不能为下列应用程序转译:
- 内核拓展程序
- 虚拟
x86_64
平台的虚拟机程序
另外,Rosetta 无法支持 x86_64 指令集中提供的一些较新的指令集特性:包括 AVX、AVX2 与 AVX512 向量指令集。包含这些指令集的程序可能无法在搭载 Apple M1 芯片的设备上运行。
对于 macOS 开发者……
Apple 在开发者文档中提供了 sysctlbyname
函数用于检测这些向量指令集是否可用于用户的设备上。比如,要检测 AVX512 指令集在用户设备上是否可用,则需检查 hw.optional.avx512f
属性值。
另外,应用程序开发者能够使用 sysctlbyname
函数的 sysctl.proc_translated
标识符辨别应用程序是否经转译运行,Apple 开发者网站给出的示例代码如下:
int processIsTranslated() {
int ret = 0;
size_t size = sizeof(ret);
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1)
{
if (errno == ENOENT)
return 0;
return -1;
}
return ret;
}
拓展阅读
- 2020 年 6 月苹果宣布为 macOS 提供应用程序转译支持的文章《Apple announces Mac transition to Apple silicon》