如何在 M1 芯片的 MacBook 上编译需要 SSE2 的项目?

How to compile a project which requires SSE2 on MacBook with M1 chip?

我需要在我的带有 M1 芯片的 macbook air (os Monterey) 上安装一个需要 SSE2 的软件。

当我尝试编译项目时收到以下错误:

/libRootFftwWrapper/vectorclass/vectorclass.h:38:4: error: Please compile for the SSE2 instruction set or higher
  #error Please compile for the SSE2 instruction set or higher
   ^

并且错误消息链接到代码中的以下行:

#include "instrset.h"        // Select supported instruction set

#if INSTRSET < 2             // SSE2 required
  #error Please compile for the SSE2 instruction set or higher
#else

我知道只有 Intel 芯片配备了 SSE2,但是有什么翻译器可以帮助我构建这个项目吗?

更新:问题已解决。答案在答案部分。

我设法使用 rosetta 2 编译了该项目,正如下面评论中所建议的那样。 为了安装 rosetta,我使用了以下命令:

$ softwareupdate --install-rosetta

然后我使用以下方法为 x86_64 arch 安装了 Homebrew、clang 和 cmake:

$ arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ arch -x86_64 /usr/local/bin/brew install llvm
$ arch -x86_64 /usr/local/bin/brew install cmake

我还必须 re-tap Homebrew 使用:

$ rm -rf "/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core"
$ arch -x86_64 /usr/local/bin/brew tap homebrew/core 

正如 brew doctor 所建议的那样。

最后,项目在去掉之前生成的CMakeCache后编译成功:

$ make clean
$ arch -x86_64 /usr/local/bin/cmake build_dir 
$ make 
$ make install 

Alisa 的解决方案对某些人来说可能不是最优的,所以这里有一个替代方案。

Rosetta 2 基本上是一个模拟器;它采用编译后的 x86 机器码并在 ARM 上运行。我没有 M1 CPU,但从各方面来看,它在这方面做得 非常

也就是说,直接针对 Arm CPU 编译代码通常比依赖 Rosetta 更好。编译器通常比模拟器拥有更多关于代码如何工作的信息,模拟器必须在所有额外的上下文被丢弃后运行,因此它有时可以更有效地优化代码。

Alisa 运行 遇到的问题是 SSE 内在函数并非设计为可移植的,它们旨在让人们通过编写与底层架构紧密耦合的代码来获得更好的性能。

有几个项目允许您使用 NEON 编译 SSE 代码,您可以将其视为 Arm 的 SSE 版本,方法是提供 SSE API 的替代实现。最受欢迎的两个可能是 SSE2NEON and SIMD Everywhere (SIMDe)(完全披露:我是后者的首席开发人员)。

SSE2NEON 只是使用 NEON 实现 SSE。 SIMDe 提供了许多实现,包括 NEON、AltiVec/VSX (POWER)、WebAssembly SIMD、z/Architecture 等,以及随处可用的可移植后备。

这两个项目的工作原理基本相同:不是包含 <xmmintrin.h>(或其他一些特定于 x86 的 header,这取决于您要使用的 ISA),而是包含 SSE2NEON 或 SIMDe。然后添加任何相关的编译器标志来设置目标(例如,-march=armv8-a+simd),就可以了。

如果性能不是主要问题,Rosetta 2 可能是最简单的选择。否则你可能想看看 SSE2NEON 或 SIMDe。

另一个考虑因素是您是只想快速修复还是最终想将代码移植到 Arm...Rosetta 2 不是 long-term 解决方案,而是 stop-gap 允许现有代码在人们移植他们的代码时继续工作。 SSE2NEON 和 SIMDe 都可以在同一个可执行文件中混合 x86 和 Arm SIMD 代码,因此您可以随着时间的推移逐渐移植代码,而不必翻转一个大开关来从 x86 过渡到 Arm。