visual-c++ - 如何在 MSVC 中启用 SSE4.1 和 SSE3(但不是 AVX)

标签 visual-c++ sse simd sse4

我正在尝试使用 MSVC 启用不同的 simd 支持。
有一个页面在谈论启用一些 simd,例如 SSE2、AVX、AVX2
https://docs.microsoft.com/en-us/cpp/build/reference/arch-x86?redirectedfrom=MSDN &view=vs-2019
但是,它没有提到如何启用其他 simd 优化,例如 SSE4.1、SSE4.2、SSE3
是否可以在不启用 AVX 的情况下启用这些?
另外,看起来在 MSVC2017 中/arch:SSE2 不再受支持/需要,我是否可以假设默认情况下也启用了 SSE3/SSE4.1/SSE4.2?

最佳答案

VC++ 编译器没有你想象的那么聪明。以下是这些设置的工作原理。
当您构建 32 位代码并启用 SSE1 或 SSE2 时,它会启用 自动 矢量化为相应的指令集。
当您构建 64 位代码时,SSE1 和 SSE2 都是指令集的一部分,世界上所有的 AMD64 处理器都需要支持这两者。这就是为什么您收到/arch:SSE2 警告的原因。
当您设置 AVX 时,编译器会做两件事,启用 自动 矢量化到 AVX1,还将指令编码(对于所有这些,SSE、AVX、手动矢量化和自动矢量化)从传统切换到 VEX . VEX 是个好东西,可以将未对齐的 RAM 读取融合到其他指令中。它还解决了可能影响性能的依赖问题,VEX 编码 vaddps xmm0, xmm0, xmm1ymm0 的高 16 字节清零, 而传统编码 addps xmm0, xmm0, xmm1将数据保存在那里。
当你设置 AVX2 时,它会做一些小的优化,最显着的是像 _mm_set1_epi32 这样的东西。可以编译成vpbroadcastd .也像 AVX1 一样将编码切换到 VEX。
注意我用粗体标记了自动。 Microsoft 编译器不执行运行时分派(dispatch)或 cpuid 检查,并且自动向量化器不使用 SSE3 或 4.1。如果您正在编写手动矢量化代码,编译器不会执行回退,而是会发出您要求的任何指令。当存在时,AVX/AVX2 设置仅影响它们的编码。
如果您想编写使用 SSE3、SSSE3、SSE 4.1、FMA3、AES、SHA 等的手动矢量化代码,您不需要启用任何东西。您只需要包含相关的头文件,并且最好在运行时确保 CPU 拥有它们。最后一部分,我通常调用 __cpuid 在启动和检查这些位的早期,这是为了显示有关不受支持的 CPU 的可理解错误消息,而不是稍后的硬粉碎。

关于visual-c++ - 如何在 MSVC 中启用 SSE4.1 和 SSE3(但不是 AVX),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64053597/

相关文章:

assembly - 如何将浮点常量值移动到 xmm 寄存器中?

c - 如何解决vfmadd213ps的 "illegal instruction"?

performance - 为什么 GCC 和 Clang 不使用 cvtss2sd [内存]?

optimization - 调整 MIT 的 bitcount 算法以并行计算单词?

c++ - 了解 __m128i 标志的位对齐

c++ - openmp collapse with inner loop reduction

c++ - 使用 Visual C++ 2010 在两个窗体之间传递数据

c++ - 为什么我们需要在 C++ 中导出一个类?

c++ - 为什么 std::variant 不能保存数组对象类型而 union 可以?

c++ - 如何使 MSVC 调试版本运行得更快