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

Visual c++ 如何在MSVC中启用SSE4.1和SSE3(但不是AVX),visual-c++,sse,simd,sse4,Visual C++,Sse,Simd,Sse4,我正在尝试使用MSVC启用不同的simd支持 有一页讨论如何启用某些simd,如SSE2、AVX、AVX2 &;视图=vs-2019 但是,它没有提到如何启用其他simd优化,例如SSE4.1、SSE4.2、SSE3 是否可以在不启用AVX的情况下启用这些功能 另外,看起来在MSVC2017/arch中:不再支持/需要SSE2,我可以假设默认情况下也启用了SSE3/SSE4.1/SSE4.2吗?VC++编译器没有您想象的那么聪明。以下是这些设置的工作原理 当您构建32位代码并启用SSE1或

我正在尝试使用MSVC启用不同的simd支持

有一页讨论如何启用某些simd,如SSE2、AVX、AVX2 &;视图=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是一个好东西,可以将未对齐的RAM读入其他指令。它还解决了可能影响性能的依赖性问题,VEX编码的
vaddps xmm0、xmm0、xmm1
ymm0
中较高的16个字节归零,而传统编码的
addps xmm0、xmm0、xmm1
将数据保留在那里

当您设置AVX2时,它会进行一些小的优化,最明显的是像
\u mm\u set1\u epi32
这样的东西可能会编译成
vpbroadcasted
。对于AVX1,也将编码切换为VEX-like

注:我用粗体标记为自动。Microsoft编译器不执行运行时分派或cpuid检查,自动矢量器也不使用SSE3或4.1。如果您正在手动编写矢量化代码,编译器将不会执行回退,而是会发出您要求的任何指令。存在时,AVX/AVX2设置仅影响其编码


如果您想编写使用SSE3、SSSE3、SSE4.1、FMA3、AES、SHA等的手动矢量化代码,则无需启用任何功能。您只需要包含相关的头文件,并在理想情况下确保CPU在运行时拥有它们。对于最后一部分,我通常在启动时提前调用并检查这些位,这是为了显示一条关于不支持的CPU的可理解的错误消息,而不是稍后的硬挤压。

我可以假设SSE3/SSE4.1/SSE4.2在默认情况下也已启用吗?-不,SSE2是x86-64的基线。每个x86-64 CPU都保证有SSE2。我想这就是为什么你不需要一个选择。但是有些AMD x86-64 CPU没有SSE3,有些Intel x86-64 CPU没有SSE4.1(例如第一代Core 2)。不过,我不知道你问题的答案。您可能只能通过intrinsic获得没有AVX的SSE4,因为MSVC在这方面很差(或者是围绕运行时调度模型设计的,而不是编译时),但可能有一个MSVC选项。您可以使用像clang这样的编译器,其中可以使用
-O3-msse4.1
-O3-march=penryn