首页 > 解决方案 > Xcode Apple Clang 启用 avx512

问题描述

在 Xcode(版本 10.1 (10B61))中,我使用如下宏来检测 AVX512 支持。

#ifdef __SSE4_1__
#error "sse4_1"
#endif

#ifdef __AVX__
#error "avx"
#endif

#ifdef __AVX2__
#error "avx2"
#endif

#ifdef __AVX512__
#error "avx512"
#endif

在默认构建设置中,SSE4_1处于活动状态,但 avx、avx2 并没有。当我在 Building Settings-->Apple Clang-Custom Compiler Flags-->Other C Flags 添加 -mavx 以启用AVX 进一步添加-mavx2以启用AVXAVX2,但未知参数:'-mavx512'。你如何启用avx512并检测它?似乎很少有宏可以检测 avx512。

#define __AVX512BW__ 1  
#define __AVX512CD__ 1  
#define __AVX512DQ__ 1  
#define __AVX512F__ 1  
#define __AVX512VL__ 1   

它们之间有什么区别?

标签: xcodeclangavxavx2avx512

解决方案


AVX512 不是一个单独的扩展,在这种情况下没有足够具体的含义来有用。编译器只处理特定的CPU 功能,如 AVX512F、AVX512DQ、AVX512CD 等。

所有支持任何 AVX512 扩展的 CPU 都必须支持 AVX512F,即“基础”。 AVX512F其他 AVX512 扩展构建的基线 AVX512 扩展。

在想要使用 AVX512 内在函数的代码中,您应该查看https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512并选择一组可在您关心的 CPU 上一起使用的扩展,例如当前可用的 Skylake-X 上的 F + CD 和 VL、DQ、BW。

然后例如在使用256 位向量或其他东西的 #if defined(__AVX512BW__) && defined(__AVX512VL__)代码之前使用。暗示;这是您不必单独检查的一个扩展。vpermt2w__AVX512(anything)____AVX512F__

但是,如果您使用 AVX512F 指令,他们是的,只需检查该宏即可。


您几乎不应该-mavx512f直接使用:使用-march=skylake-avx512、、-march=knl-march=native。或者在未来,-march=icelake或者别的什么。

  • 编译器知道哪些 CPU 支持哪些扩展集(或者可以检测您正在编译的机器支持哪些扩展)。它们有很多,而忽略重要的一些,例如 AVX512VL(支持 128 位和 256 位向量上的 AVX512 指令)或 Xeon Phi 的 AVX512ER(速度快1/x1/sqrt(x)精度是普通 AVX512 14 位版本的两倍)可以严重损害性能。如果您在 Xeon Phi 上进行任何除法或 log/exp,特别是 AVX512ER 非常重要,因为与 Skylake 相比,KNL 上的全精度除法非常慢。
  • -march=x意味着-mtune=x,也启用与目标相关的调整选项。KNL 基本上是带有 AVX512 的 Silvermont,与-mtune=skylake-avx512.

这些是你一般不应该-mfma -mavx2直接使用的相同原因,除了目前没有带有 AVX512 的 AMD CPU,因此只有 2 个主要调优目标(至强融核和主流 Skylake/CannonLake/Icelake),并且它们还支持不同的设置AVX512 扩展。不幸的是,没有-mtune=generic-avx2调整设置,但 Ryzen 支持 Haswell 所做的几乎所有扩展(以及那些它不 GCC / clang 不会自动使用的扩展,例如事务内存),因此-march=haswell使用 FMA 为 CPU 调整代码可能是合理的, AVX2, popcnt 等,在 Ryzen 上不用受太多苦。


也相关(对于 GCC,目前可能不铿锵声 。https ://gcc.gnu.org/onlinedocs/gcc/x86-Options.html ):

  • -mprefer-vector-width=256默认情况下使用 256 位向量自动向量化,以防大部分时间花在非向量化循环中。在 Intel Xeon CPU 上使用 512 位向量会显着降低最大涡轮时钟速度(在 Skylake-X 的 i9 桌面版本上可能没有那么大),因此在小分散的情况下使用 512 位向量可能会明显减慢你的程序的位。所以 256 是tune=skylake-avx512GCC 的默认值,但 KNL 使用 512。

  • -mprefer-avx-128-mprefer-vector-width=选项的旧版本,在 AVX512 存在之前。

即使在相同的向量宽度下,使用 AVX512 掩码寄存器、32 个向量寄存器和/或其新指令也可能是一个重大胜利,因此即使您不想使用 512 位向量宽度,启用 AVX512 也是有意义的。(虽然有时使用内在函数或自动向量化的代码编译的方式会更糟,而不是更好,如果 AVX512 比较寄存器版本的比较完全可用。但希望像这样的反优化错误将被整理为 AVX512应用越来越广泛。)


推荐阅读