我正在尝试使用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吗?
发布于 2020-09-25 12:40:28
VC++编译器并没有你想象的那么智能。下面是这些设置的工作原理。
当您构建32位代码并启用SSE1或SSE2时,它将启用自动向量化到各自的指令集。
在构建64位代码时,SSE1和SSE2都是指令集的一部分,世界上所有的AMD64处理器都需要同时支持这两种指令集。这就是为什么你会收到/arch:SSE2的警告。
当你设置AVX时,编译器做两件事,启用自动矢量化到AVX1,也切换指令编码(对于所有它们,包括SSE,AVX,手动矢量化和自动矢量化)从遗留到VEX。VEX是个好东西,可以将未对齐的RAM读操作融合到其他指令中。它还解决了可能影响性能的依赖问题,VEX编码的vaddps xmm0, xmm0, xmm1将ymm0的高16字节置零,而传统编码的addps xmm0, xmm0, xmm1则将数据保留在那里。
当你设置AVX2时,它会做一些小的优化,最值得注意的是像_mm_set1_epi32这样的东西可能会编译成vpbroadcastd。也会将编码转换为VEX,就像AVX1一样。
注意,我用粗体标记了automatic。微软编译器不做运行时调度或cpuid检查,自动向量器也不使用SSE3或4.1。如果你正在手工编写向量化的代码,编译器不会做回退,它会发出你要求的任何指令。如果存在,AVX/AVX2设置仅影响其编码。
如果你想手动编写使用SSE3,SSSE3,SSE4.1,FMA3,AES,SHA等的矢量化代码,你不需要启用任何东西。您只需要包含相关的标头,并且理想情况下确保在运行时CPU具有这些标头。对于最后一部分,我通常在启动早期调用__cpuid并检查这些位,这是为了显示关于不支持的CPU的可理解的错误消息,而不是稍后的硬崩溃。
发布于 2021-09-25 17:18:55
显然,您可以以未记录的方式作为/d2...选项传递/arch:选项。比如/d2archAVX。
以这种方式接受/d2archSSE42 (但不接受SSE41或SSE3)。
@Peter在评论中指出了一个/d2archSSE42发挥作用的案例:https://godbolt.org/z/EsjW4vTne
https://stackoverflow.com/questions/64053597
复制相似问题