如何在 Visual Studio 2017 15.5 中禁用 AVX?

Posted

技术标签:

【中文标题】如何在 Visual Studio 2017 15.5 中禁用 AVX?【英文标题】:How to disable AVX in Visual Studio 2017 15.5? 【发布时间】:2017-12-13 19:42:27 【问题描述】:

似乎从最近的更新 Visual Studio 2017 (15.5) 开始,即使“启用增强指令集”设置为“未设置”,它也会使用 AVX 扩展(对于 x64 构建)生成代码,根据到工具提示应该只允许 SSE2 指令。 尝试将其设置为 /arch:SSE2 或 /arch:IA32 会导致编译器警告“忽略未知选项 '/arch:IA32'”(或相应的 SSE2),根据https://connect.microsoft.com/VisualStudio/feedback/details/1217151,这是预期的行为。 那么现在有什么办法可以让编译器不生成 AVX 特定的代码呢?

更新

这已在 15.7 中修复

【问题讨论】:

你是这个人吗? developercommunity.visualstudio.com/content/problem/166375/… 无论哪种方式,请在此处发布 SSCCE。 我不是那个人,但非常感谢你的链接,它看起来就像我的情况 【参考方案1】:

在正常情况下,默认启用的循环自动矢量化器还可以使用扩展指令集(例如,即使在 arch 明确设置为 SSE2 时,AVX 也是如此)。

但是,如果 cpu 不支持 AVX,它应该如何工作?编译器插入特殊的运行时 ISA 检查(通过__isa_available?)以增强指令集支持,并根据需要选择带有受支持指令的代码路径。即使arch是SSE2,它看起来也类似于现代cpu的SSE4.2 instructions emission。

在上次更新 (15.5) 中,自动矢量化至少在 x86 / x64 版本中被破坏。编译器不会插入运行时 ISA 检查并在循环向量化期间发出 AVX 指令(在我的情况下是 vpermilps)。

临时解决方案:

正如我在解决方法中所建议的那样,您可以 remove auto-vectorization 选择一个循环:

#pragma loop(no_vector)
for / while / do while ...

不幸的是,这是一个快速的 hack,因为每个循环都可能被矢量化,并且在任何地方都插入这样的 pragma 是不切实际的。当然,你也可以得到性能下降。

另一个临时解决方案是尝试/d2Qvec-sse2only 内部编译器开关以在自动矢量化期间仅使用 SSE2(至少,它应该适用于 Visual Studio 2013)。此开关未记录在案,如有更改,恕不另行通知。

更新: 正如 Cheney Wang 所说,错误已发送给 C++ 团队,因此您可以在 community item 跟踪其状态。

【讨论】:

"编译器插入特殊的运行时 ISA 检查" 我认为只有 MSVC 隐含地为矢量化执行此操作。我猜ICC会为某些编译器选项执行此操作。但是 GCC 和 Clang 并没有隐含地这样做。相反,程序员在编译时选择指令集。 @Zboson 感谢您的澄清!【参考方案2】:

IA32 选项不适用于 x64 二进制文件,因为 SSE2 是 x86_64 指令集的必需部分。 不设置选项应该编译为 SSE2 级别。

【讨论】:

以上是关于如何在 Visual Studio 2017 15.5 中禁用 AVX?的主要内容,如果未能解决你的问题,请参考以下文章

关于Light主题的Visual Studio 2017 v15.7.2代码镜头问题

如何使用 Visual Studio 2017 在 Windows 中查找 Android sdkmanager 安装路径

Visual Studio 2017 版本 15.5.5

Visual Studio 2017 15.5 打破 C++ TypeDefs

远程部署/调试 Visual Studio 2017 .NET Core

为啥“if constexpr”不能与 Visual Studio 2017 15.3 一起编译?