Xcode Apple Clang 启用 avx512

Xcode Apple Clang enable 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   

它们有什么区别?

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

所有支持任何 AVX512 扩展的 CPU 都必须支持 AVX512F,"Foundation"。 AVX512F 其他 AVX512 扩展所基于的基线 AVX512 扩展。

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

然后例如在对 256 位向量或其他内容使用 vpermt2w 的代码之前使用 #if defined(__AVX512BW__) && defined(__AVX512VL__)__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 位版本)可能会显着影响性能。特别是 AVX512ER 非常重要,如果你在 Xeon Phi 上做任何除法或 log/exp,因为与 Skylake 相比,全精度除法在 KNL 上非常慢。
  • -march=x 意味着 -mtune=x,同时启用与目标相关的 调整 选项。 KNL 基本上是安装了 AVX512 的 Silvermont,与 -mtune=skylake-avx512.
  • 有显着差异

这些和你一般不应该直接使用-mfma -mavx2的原因是一样的,除了目前没有AMDCPUs与AVX512,所以有只有 2 个主要调整目标(Xeon Phi 和主流 Skylake/CannonLake/Icelake),它们还支持不同的 AVX512 扩展集。不幸的是没有 -mtune=generic-avx2 调整设置,但 Ryzen 支持 Haswell 所做的几乎所有扩展(并且它不支持 GCC / clang 的扩展不会自动使用,例如事务内存),所以 -march=haswell 可能使用 FMA、AVX2、popcnt 等为 CPUs 调整代码是合理的,而不会在 Ryzen 上受到太多影响。


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

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

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

使用 AVX512 掩码寄存器,32 个向量寄存器,and/or 它的新指令,即使在相同的向量宽度下也可以是一个重要的胜利,所以启用 AVX512 是有意义的,即使你不想使用 512 位矢量宽度。 (虽然有时使用内部函数或自动矢量化的代码会以更糟糕的方式编译,而不是更好,如果 AVX512 compare-into-register versions of comparison is available at all.但希望像这样的反优化错误将被整理为 AVX512变得越来越广泛。)