visual-c++ - visual studio编译代码时arch参数如何使用?

标签 visual-c++ compiler-optimization simd intrinsics avx

我的目标是开发代码,在 SIMD 指令可用时使用 SIMD 指令进行编译,而在它们不可用时不使用。更具体地说,在我的 C 代码中,我进行了明确的 SIMD 调用,并根据我提取的处理器信息检查这些调用是否有效。

我有很多问题,但在输入足够多之后,SO 指出了我: Detecting SIMD instruction sets to be used with C++ Macros in Visual Studio 2015

唯一剩下的问题是 /arch 标志如何影响显式 SIMD 代码?即使您的拱门未设置,这仍然有效吗?例如,我可以在没有/arch:AVX2 的情况下编写 AVX2 调用吗?

最佳答案

这里有几个答案。

首先,经典的 Intel 32 位 x86 代码使用 x87 指令集进行浮点运算,编译器将使用 floatdouble 类型为 x87 生成代码.长期以来,这是 Visual C++ 编译器在构建 32 位时的默认行为。您可以通过 /arch:IA32 强制它与 32 位代码一起使用——此开关对 64 位无效。

对于 AMD64 64 位代码(英特尔也将其用于 64 位代码,通常称为 x64),x87 指令集与 3DNow 一起被弃用!和在 64 位模式下运行时的 Intel MMX 指令。所有 floatdouble 类型的代码都是使用 SSE/SSE2 生成的,尽管不一定使用 XMM 的完整 4 个 float 或 2 个 double 元素宽度> 注册。相反,编译器通常会生成仅使用 XML 的 SSE/SSE2 指令的标量版本——实际上是 __fastcall 64 位调用约定和 .NET 编码规则结果只处理 XML。这是为 64 位构建时 Visual C++ 编译器的默认行为。您还可以通过 /arch:SSE/arch:SSE2 开关将相同的 codegen 用于 32 位——这些开关对 x64 无效,因为它们具有已经到了。

Starting with Visual C++ 2015, /arch:SSE2 is the default for 32-bit code gen and is implicitly required for all 64-bit code gen.

这将我们带到 /arch::AVX。对于 32 位和 64 位代码生成器,这让编译器使用 VEX 前缀来编码 SSE/SSE2 指令(由我上面提到的数学编译器生成,或者通过显式使用编译器内部函数生成)。此编码使用 3 操作数 (dest, src1, src2) 而不是英特尔代码的传统 2 操作数 (dest/src1, src2)。这样做的最终结果是所有 SSE/SSE2 代码生成都可以更有效地使用可用寄存器。这实际上是使用 /arch:AVX 为您带来的大部分内容。

编译器的其他方面也使用 /arch 开关设置,例如优化的 memcpy 和可供自动使用的指令集-/O2/Ox 构建等中的矢量化器。编译器还假设如果您使用 /arch:AVX 它是免费使用的SSE3、SSSE3、SSE4.1、SSE4.2 或 AVX 指令以及 SSE/SSE2。

使用 /arch:AVX2,您可以使用 VEX 前缀和指令集获得相同的行为,而且编译器可以选择优化代码以使用融合乘加 (FMA3) 指令AVX2 需要。自动矢量化器也可以在激活此开关的情况下使用 AVX2 指令。

TL;DR:如果您使用编译器内在函数,您就有责任确保它们不会在运行时因无效指令异常而崩溃。 /arch 开关只是让您告诉编译器在任何地方都使用高级指令集和编码。

有关详细信息,请参阅此博客系列:DirectXMath: SSE, SSE2, and ARM-NEON ; SSE3 and SSSE3 ; SSE4.1 and SSE 4.2 ; AVX ; F16C and FMA ; AVX2 ;和 ARM64 .

关于visual-c++ - visual studio编译代码时arch参数如何使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50827769/

相关文章:

c - GCC 如何优化循环内递增的未使用变量?

c++ - 具有递归模板参数包函数是否为每次迭代创建特定函数?

c++ - avx浮点按位逻辑运算的原因是什么?

c - 如何将 __m128d simd vector 的内容存储为 double 而不将其作为 union 访问?

c++ - 对齐和SSE异常行为

c++ - 将 MSVC++ .lib 文件与 mingw 一起使用。名称修改

c# - DLL导入使用SYSTEMTIME

multithreading - C++/CLI 线程 - InvalidProgramException

c++ - 如何从 Lua 脚本调用 C++ 函数?

c - GCC 优化器的未初始化警告