【问题标题】:How do I enable SSE4.1 and SSE3 (but NOT AVX) in MSVC如何在 MSVC 中启用 SSE4.1 和 SSE3(但不是 AVX)
【发布时间】:2021-01-11 04:02:33
【问题描述】:

我正在尝试使用 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 也默认启用吗?

【问题讨论】:

  • 我可以假设 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)。
  • 不过,我不知道您的问题的答案。您可能只能通过内在函数获得没有 AVX 的 SSE4,因为 MSVC 在这方面很糟糕(或围绕运行时调度模型设计,而不是编译时),但也许有一个 MSVC 选项。您可以使用像 clang 这样的编译器,您可以在其中使用 -O3 -msse4.1-O3 -march=penryn

标签: visual-c++ sse simd sse4


【解决方案1】:

VC++ 编译器没有你想象的那么聪明。以下是这些设置的工作原理。

当您构建 32 位代码并启用 SSE1 或 SSE2 时,它会启用自动向量化到各自的指令集。

当您构建 64 位代码时,SSE1 和 SSE2 都是指令集的一部分,全球所有 AMD64 处理器都需要同时支持这两者。这就是您收到 /arch:SSE2 警告的原因。

当您设置 AVX 时,编译器会做 2 件事,启用 自动 向量化到 AVX1,还会从遗留给VEX。 VEX 是个好东西,可以将未对齐的 RAM 读取融合到其他指令中。它还解决了可能影响性能的依赖性问题,VEX 编码的vaddps xmm0, xmm0, xmm1ymm0 的高16 字节归零,而传统编码的addps xmm0, 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 的可理解错误消息,而不是稍后的硬崩溃。

【讨论】:

    【解决方案2】:

    显然您可以将/arch: 选项以未记录的方式作为/d2... 选项传递。喜欢/d2archAVX

    /d2archSSE42 以这种方式被接受(但不是 SSE41 或 SSE3)。

    @Peter 在评论中指出/d2archSSE42 有所作为的案例:https://godbolt.org/z/EsjW4vTne

    【讨论】:

    • 使用 SSE4.1 进行自动矢量化的一个很好的候选者是可以使用 pminsd,压缩整数最小值。启用/d2archSSE42 使MSVC 省略检查cmp __isa_available, 2 和回退标量循环(MSVC 是愚蠢的,不知道如何使用SSE2 pcmpgtd 进行回退)。 godbolt.org/z/EsjW4vTne。不过,我必须写出一个条件表达式; MSVC 无法使用 std::min 进行矢量化。 GCC当然很好。此外,pmulld 是一个更简单的矢量化对象,arr[i] *= 1234;,是的,MSVC 也这样做。
    • @PeterCordes,顺便说一句,MSVC 很快将在bitset 中使用popcnt/arch:AVXmy PR merged;与 PR 中的文件一起查看它:godbolt.org/z/K9vEhnsMx - 请注意,无条件 popcnt 是通过 /arch:AVX 启用的
    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多