【问题标题】:What is the minimum supported SSE flag that can be enabled on macOS?可以在 macOS 上启用的最低支持 SSE 标志是多少?
【发布时间】:2018-02-05 14:55:36
【问题描述】:

现在我使用的大部分硬件都支持 SSE2。在 Windows 和 Linux 上,我有一些代码来测试 SSE 支持。我在某处读到 macOS 支持 SSE 很长时间了,但我不知道可以启用的最低版本。最终的二进制文件将被复制到其他 macOS 平台,所以我不能像 GCC 那样使用-march=native

如果在所有构建中默认启用它,我是否必须在构建代码时传递 -msse-msse2 标志?

这是我的编译器版本:

Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix

这里是 uname -a 的输出

uname -a
Darwin mme.local 14.1.0 Darwin Kernel Version 14.1.0: Mon Dec 22 23:10:38 PST 2014; root:xnu-2782.10.72~2/RELEASE_X86_64 x86_64

这里是 sysctl machdep.cpu.features 的输出

machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 DTES64 MON DSCPL VMX EST TM2 SSSE3 CX16 TPR PDCM SSE4.1 SSE4.2 POPCNT

【问题讨论】:

  • 如果您使用的是 Xcode,请查看 CLANG_X86_VECTOR_INSTRUCTIONS 构建设置。我认为您可以放心地假设任何足以运行 OS X 的新事物(即过去 10-15 年的任何事物)都具有最低 SSE3(甚至 SSSE3)。
  • @PaulR 感谢您提供信息。我没有使用 XCode 项目。根据您的评论,我可以假设 sse2。

标签: c++ macos optimization compiler-optimization sse


【解决方案1】:

默认为 x86-64 启用 SSE2,因为它是 x86-64 ISA 的必需部分。

由于 Apple 从未销售过任何 AMD 或 Pentium4 CPU,因此 OS X 上的 x86-64 也意味着 SSSE3(第一代 Core2)。最初的 x86 Mac 是 Core(不是 Core2),但它们只是 32 位的。不幸的是,您不能假设 SSE4.1 或 -mpopcnt

我建议-march=core2 -mtune=haswell。 (-mtune 不会影响兼容性,Haswell 调优对于实际的 Core2 或 Nehalem 硬件应该不会有什么坏处。请参阅http://agner.org/optimize/ 标签 wiki 中的链接,了解有关微架构的详细信息(编译器生成)汇编语言在不同的 CPU 上或快或慢。)。

(请参阅How does mtune actually work?,了解不同调整导致不同指令选择而不更改所需 ISA 扩展的示例。)

-march=core2 启用 core2 支持的所有功能,而不仅仅是 SSSE3。由于您不关心您的代码在 AMD CPU 上表现良好(因为它是 OS X),因此您可以针对 Intel CPU 进行调整。还有-mtune=intel比较通用,不过Haswell应该是合理的。

如果有人在非 Apple 硬件上的古老 CPU 上安装 OS X,您可能会错过对 Hackintosh 系统的支持,但如果 OS X 可以在 AMD Athlon64 / PhenomII 或 Intel P4 上运行,则需要 IDK。

如果能够启用像 -mpopcnt 这样的 Nehalem 功能会很不错,但 Core 2 第一代和第二代(Conroe 和 Penryn)缺少这些功能。甚至 SSE4.1 在第一代 Core 2 上也不可用。


还可以构建带有基线和 Haswell 切片的胖二进制文件x86_64x86_64h。 Stephen Cannon 说(在下面的 cmets 中)“x86_64h 切片将在 Haswell 和更高版本的 µarches 上自动运行”。 (其他 uarches 的切片目前不是一个选项,但大多数程序几乎没有什么好处。)

您的x86_64(非Haswell)切片可能应该使用-march=core2 -mtune=sandybridge 构建。

Haswell 引入了 AVX2、FMA 和 BMI2,所以 -march=haswell 非常适合 Broadwell / Skylake / Kaby Lake / Coffee Lake。 (对于调优选项和 ISA 扩展:gcc -march=haswell 禁用 -mavx256-split-unaligned-load 并存储,而 -mavx + tune=default 或 sandybridge 启用它。它 sucks on Haswell 尤其是当它创建 shuffle-port 瓶颈时。真的当你的数据几乎总是对齐,或者真的总是对齐但你只是没有告诉编译器时,这是愚蠢的。

Broadwell 推出了相当小众的 ADOX/ADCX(并行运行两个扩展精度的添加依赖链),Skylake 推出了clflushopt,但并没有广泛使用。

不过,Skylake 和大多数 Broadwell CPU 确实具有工作事务内存,这对于一些细粒度的多线程情况可能很重要。 (Haswell 本来打算拥有它,但在实现中发现了一个罕见的错误后,它在微码更新中被禁用。)

AVX512 是下一个被广泛使用但 Haswell 没有的大件,所以也许 Apple 会在某个时候增加对 Cannonlake 或 Ice Lake 切片的支持。

我不建议为 Broadwell 或 Skylake 单独构建(使用任何调度机制),除非您知道可以利用特定的新功能并且它会产生重大影响。

但它可能对 Sandybridge 有用,对于没有 AVX2 的 AVX 支持,特别是对于 256 位 FP 数学,但也可以将 movdqa 指令保存在整数 128 位向量代码中。也适用于 SSE4.x 和 popcnt。并且在使用 dec/jnz 的扩展精度 adc 循环中没有部分标志问题。

【讨论】:

  • SSSE3 是针对任意 macOS 版本的 64 位进程的正确基线。如果针对 macOS 10.12 或更高版本,您也可以假设 SSE4.1,因为 10.11.x 是支持 Penryn 之前硬件的最后一个操作系统版本。
  • 我还应该注意,可以使用 x86_64x86_64h 切片构建胖 macOS 二进制文件; x86_64h 切片将在 Haswell 和更高版本的 µarches 上自动运行,并暗示大多数 HSW 新指令(FMA、AVX2、BMI 等)。
  • @StephenCanon:很好! Haswell介绍了很多好东西;很高兴将其作为基线(尤其是 BMI2,当您可以让编译器在任何地方使用它时,它最有用)。
  • @saagarjha 不,仅适用于 Haswell。添加新切片的成本相对较高,因此并非每个新的 uArch 都会发生这种情况,但 Haswell 对 ISA 进行了很多重大改进。
  • @Zboson: -mtune 在不改变基线目标的情况下进行调整。例如在某些情况下,AMD Phenom CPU 需要rep ret,但英特尔不需要,所以-mtune=haswell 放弃了它。使用 256 位向量进行向量化并不总是值得的,因此 -mtune=bdver1(first-gen Bulldozer) 将(我认为/希望)更喜欢 128 位向量,即使指定了 -mavx-mtune= 任何不古老的东西也将针对 cmp/jcc 宏融合进行优化,而不是尝试尽早执行 cmp 以便标志准备就绪。另见How does mtune actually work?
猜你喜欢
  • 1970-01-01
  • 2021-04-26
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多