xcode - 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以启用AVX和AVX2,但未知参数:'-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,即“基础”。 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/x
,1/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-avx512
GCC 的默认值,但 KNL 使用 512。-mprefer-avx-128
该-mprefer-vector-width=
选项的旧版本,在 AVX512 存在之前。
即使在相同的向量宽度下,使用 AVX512 掩码寄存器、32 个向量寄存器和/或其新指令也可能是一个重大胜利,因此即使您不想使用 512 位向量宽度,启用 AVX512 也是有意义的。(虽然有时使用内在函数或自动向量化的代码编译的方式会更糟,而不是更好,如果 AVX512 比较寄存器版本的比较完全可用。但希望像这样的反优化错误将被整理为 AVX512应用越来越广泛。)
推荐阅读
- javascript - 收到这样的错误,无法获取 FCM 令牌
- reactjs - 单个 SPA React 应用程序微前端
- c - 打开没有套接字的 tcp/udp 端口
- node.js - NodeJS:API在循环执行完成后不返回响应,尽管它在循环内返回
- python - 如何为我的记录器记录特定级别,并将其余部分保持在另一个级别
- javascript - 如何在元素上运行 xpath
- java - 使用三重嵌套 for 循环来增加打印行的长度和数量
- html - 如何使用 TailwindCSS 填充屏幕的其余高度
- flutter - Flutter:覆盖核心常量的正确方法是什么?
- postgresql - 使用 lambda 和 aurora postgresql 时如何处理数据库模式迁移?