如何在MSVC中启用SSE4.1和SSE3但不启用AVX

问题描述

我正在尝试使用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,xmm1将数据保留在那里。

设置AVX2时,它会进行一些次要的优化,最著名的是_mm_set1_epi32之类的东西可能会编译为vpbroadcastd。还可以像AVX1一样将编码转换为VEX。

请注意,我将粗体标记为自动。 Microsoft编译器不执行运行时调度或cpuid检查,并且自动矢量化程序不使用SSE3或4.1。如果您要编写手动矢量化的代码,则编译器不会执行后备操作,而是会发出您要求的任何指令。如果存在,AVX / AVX2设置只会影响其编码。

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...