所有支持 AVX2 的 CPU 是否也支持 SSE4.2 和 AVX?

Do all CPUs which support AVX2 also support SSE4.2 and AVX?

我计划实施 SIMD 扩展的运行时检测。是不是这样,如果我发现处理器有AVX2支持,那它也保证有SSE4.2和AVX支持吗?

如果我们设置编译器选项 -mavx2,当我们使用 AVX 或 SSE 内在函数时 GCC 不会给出错误。因此 GCC 假设 AVX2 标志的存在足以 运行 AVX 和 SSE 代码。当然,这并不能保证有人不会使用 AVX2 而没有 SSE 创建 CPU。

原则上,CPU 可以只支持 AVX2,而不支持任何 SSE4 指令(这并不像听起来那么愚蠢!)。但实际上,如果它支持 AVX2,它也支持 SSE4。

支持更新的 Intel SIMD ISA 扩展意味着支持以前的 SIMD。

AVX2 绝对意味着 AVX1。

我认为 AVX1 意味着所有 SSE/SSE2/SSE3/SSSE3/SSE4.1/SSE4.2 功能位也必须在 CPUID 中设置。如果没有正式保证,许多 事情都会做出这个假设,并且 CPU 违反它的一般用途可能在商业上不可行。

请注意 popcnt 有其自己的功能位,因此理论上您可以使用 AVX2 和 SSE4.2 使用 CPU,但不能使用 popcnt,但很多东西都处理 SSE4 .2 表示 popcnt。所以它更像是你可以在没有 SSE4.2 的情况下宣传对 popcnt 的支持。


理论上,您可以使用 AVX 创建一个 CPU(或虚拟机),但它不接受像 pcmpistri 这样的 SSE4.2 指令的非 VEX 遗留 SSE 编码,但是我认为你会违反英特尔关于 AVX 功能位暗示的保证。不确定这是否正式写在手册中,但大多数软件都会假定。

但 AVX1 确实 暗示支持 all SSE4.2 和更早的 SIMD 指令的 VEX 编码,例如vpcmpistri or vminss

gcc -mavx2 肯定意味着 AVX1 和以前的扩展,但只会发出使用 VEX 编码的代码。不过,它将定义 __SSE4_2__ 宏等等,因此 gcc 确实将 AVX2 视为暗示早期的 SSE 扩展和 popcnt,而不是 FMA、AES-NI 或 PCLMUL。即使对于 GCC,这些也是独立的功能。

(实际上你应该使用 gcc -march=nativegcc -march=znver1 或其他任何东西来启用你的 CPU 具有的所有功能, 设置调整它的选项。不只是 -mavx2 -mfma,这会使调整设置处于错误的默认值,例如将每个可能未对齐的 256 位 load/store 拆分为 128 位的一半。)

(请注意,MSVC 没有那么多的 SIMD ISA 检测宏;它有一个用于 AVX 但不是用于所有早期的 SSE* 扩展。MSVC 的模型是围绕程序将执行运行时的假设设计的 CPU 检测而不是为本地机器编译。虽然 MSVC 现在有 AVX 和 AVX2 选项来使用它们作为基线。)


请注意,AVX512 打破了传统。例如,AVX512F 意味着支持 AVX2 及其之前的所有内容,但除此之外,AVX512DQ 不会出现在 AVX512ER“之前”或“之后”。你可以(理论上)有一个,两个,或两者都没有。 (实际上,Skylake-X/Cannonlake/etc。除了 AVX512F 之外,与 Xeon Phi(Knight's Landing / Knight's Mill)只有一点重叠。https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512