我计划实现 SIMD 扩展的运行时检测。是不是如果我发现处理器支持 AVX2,就一定支持 SSE4.2 和 AVX?
最佳答案
支持最新的 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(或虚拟机),但它不接受 SSE4.2 指令的非 VEX 遗留 SSE 编码,例如 pcmpistri
,但我认为您将违反英特尔对 AVX 功能位含义的保证。不确定这是否正式写在手册中,但大多数软件都会假设这一点。
但是 AVX1 确实意味着支持所有 SSE4.2 和早期 SIMD 指令的 VEX 编码,例如vpcmpistri
或vminss
gcc -mavx2
绝对意味着 AVX1 和以前的扩展,但只会发出使用 VEX 编码的代码。不过,它将定义 __SSE4_2__ 宏等,因此 GCC 确实将 AVX2 视为暗示早期的 SSE 扩展和 popcnt ,但不包括 FMA、AES-NI 或 PCLMUL。即使对于 GCC 来说,这些也是单独的功能。
(实际上,您应该使用 gcc -march=native
或 gcc -march=znver1
或其他任何方式来启用 CPU 具有的所有功能,和 为其设置调整选项。不仅仅是 -mavx2 -mfma
,这会使调整设置处于错误的默认值,例如将每个可能未对齐的 256 位加载/存储分成 128 位两半。)
(请注意,MSVC 没有那么多 SIMD ISA 检测宏;它有一个用于 AVX 的宏,但不是用于所有早期 SSE* 扩展的宏。MSVC 的模型是围绕这样的假设而设计的:程序将执行运行时 CPU 检测,而不是执行运行时 CPU 检测。正在为本地计算机进行编译。尽管 MSVC 现在确实具有 AVX 和 AVX2 选项来使用它们作为基线。)
<小时/>请注意,AVX512 有点打破传统。 AVX512F 意味着支持 AVX2 及其之前的所有内容,但除此之外,AVX512DQ 不会出现在 AVX512ER“之前”或“之后”。 (理论上)你可以选择其中之一,也可以两者都拥有,或者两者都不拥有。 (实际上,除了 AVX512F 之外,Skylake-X/Cannonlake 等与 Xeon Phi(Knight's Landing/Knight's Mill)只有一点重叠。https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512
关于sse - 所有支持 AVX2 的 CPU 也都支持 SSE4.2 和 AVX 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53443249/