【发布时间】:2017-04-07 00:40:54
【问题描述】:
所以,这就是我想要完成的。在我的 C++ 项目中,必须使用 Microsoft Visual Studio 2015 或更高版本进行编译,根据用户 CPU 中可用的最新 SIMD 指令集,我需要一些代码具有不同的版本,其中: SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AVX、AVX2 和 AVX512。
由于我现在要寻找的是编译时 CPU 调度,我的第一个猜测是使用编译器宏可以轻松完成。然而,令我惊讶的是,在 VS2015 中很难找到关于如何使用宏实现这种 CPU 调度的信息。
例如,前一个问题“Detect the availability of SSE/SSE2 instruction set in Visual Studio”包含有关如何检测 x86 代码的 SSE 和 SSE2 的信息,但不适用于 x64 代码。虽然,他们引用了这个微软的文档:http://msdn.microsoft.com/en-us/library/b0084kay.aspx
在那里,我们只有关于如何检测 SSE、SSE2、AVX 和 AVX2 是否在编译器中启用的信息 - 不完全是 CPU 是否支持它们。此外,其他指令集(如 SSE3、SSSE3、SSE4.1、SSE4.2 和 AVX512)完全没有。
所以,我的问题变成了:我如何才能像其他编译器一样通过宏检测用户的 CPU 是否支持这些指令集,但使用 Microsoft Visual Studio 2015?
【问题讨论】:
-
除非您只打算在您编译的同一台机器上运行,否则支持的 CPU 功能集不是编译时常量,因此不能是宏。但是,如果您是,只需执行 gcc 的
-march=native的 MSVC 等效项,并查看通常的目标功能宏,如#ifdef __AVX__ -
@PeterCordes 但这正是问题所在。除了
__AVX__和__AVX2__之外没有宏。我的问题的全部意义在于调查人们是如何实现这一目标的,因为 Vistual Studio 似乎缺少这样的宏。 -
@PeterCordes 尽管这很奇怪,但似乎确实如此。 MSVC 的宏列表仅包括 AVX 和 AVX2 的宏。正如问题中所链接的,SSE2 的间接宏。这就是我的问题的由来:很难找到这方面的信息。关于你的问题,我两个都需要。对于这一部分,我需要编译时调度。但对于其他部分,我需要运行时调度——在这种情况下,我根据英特尔的手册使用
__cpuid,它在大多数情况下都运行良好。 -
要启用它们,当然 CPU 支持它们。这里的问题是说“CPU”,就像只有一个一样。如果您在旧计算机上运行编译器,构建只需要在新计算机上运行的二进制文件,您将启用 AVX。生成的二进制文件不会在构建它的计算机上运行,但它可以很好地创建它。在构建系统和编译器术语中,我们谈论“目标”与“主机”。因此启用 AVX 是一个目标选项,宏可以检测目标的基线(即启用以供编译器使用)。
-
"Microsoft 的 VS 宏检测选项中是否启用了 AVX 或 AVX2。要启用它们,当然 CPU 支持它们。" 不,这是一个错误。您可以在非 AVX CPU 上编译 AVX 代码。 “编译 AVX 代码”只是意味着编译器发出编码 AVX 操作的字节字符串。编译不涉及执行发出的字节字符串。
标签: c++ visual-studio-2015 sse avx instruction-set