【问题标题】:Microsoft C++ compiler: how to disable auto-vectorization with /O2?Microsoft C++ 编译器:如何使用 /O2 禁用自动矢量化?
【发布时间】:2012-02-12 15:24:18
【问题描述】:

如何在全局或针对特定 for 循环禁用自动矢量化 (SSE2),而不在 MSVS 2010 中恢复为 /Od?

我已经尝试了Enable Enhanced Instruction Set 的所有 3 个可能选项,包括“未设置”,但均无济于事。

P。 S. 奇怪的是,即使 /Od 也无济于事。

【问题讨论】:

  • @DanielFischer:我为什么要禁用矢量化?有两个原因:评估使用 SSE2 的性能提升,并允许与没有 SSE 的机器进行一致且有意义的性能比较。
  • 也许以下可能是相关的:stackoverflow.com/questions/1480916/…
  • 这很有意义。谢谢你满足了我的好奇心。我希望我能回报。
  • @aix:谢谢,更新了问题。

标签: c++ visual-c++ vectorization compiler-optimization


【解决方案1】:

对于特定的循环,你可以添加一个pragma:

#pragma loop(no_vector) 

这其实是documented on MSDN(虽然我是在了解之后才发现的..)

如果您不喜欢添加编译指示,可以选择使用/favor:ATOM 进行编译。这有点小技巧,但它允许您禁用自动矢量化,而无需接触源,并且仍然可以优化速度。

另外有两种优化策略/O1“优化大小”和/Os“偏爱小代码”。自动矢量化会生成更多的代码,因此如果您针对大小进行优化,则会禁用自动矢量化。

我最近通过阅读auto-vectorization cookbook 了解到这一切。请参阅“循环体规则”部分的最后一行。

免责声明:我实际上还没有使用 VS2012 编译器(需要支持 Win XP),所以我没有对此进行测试。此外,编译器开关在 2013 年或之后的工作方式可能有所不同。

【讨论】:

  • 感谢您的链接!顺便说一句,您是否看到 XP 有一个特殊的 vc11 运行时?我相信这就是您可以在 XP 中使用 2012 编译器和运行时的方式。
【解决方案2】:

您可以将for 循环隔离在一个单独的函数中,并尝试使用#pragma optimize:

// Disable all optimizations
#pragma optimize("", off)

// your function here

// Enable them back
#pragma optimize("", on)

...但这应该与/Od 仅在该特定功能上具有相同的效果,因此可能无济于事。

如果您正在为 x86(而不是 x86_64,它不起作用)进行编译,您还可以将 SSE2 指令集作为一个整体禁用(删除 /arch:SSE2 选项)。遗憾的是,它的粒度仅限于整个源文件。

【讨论】:

  • 谢谢,这应该可以工作 - /Od 中的矢量化只发生在 x64 中(为什么?),但这并不是我想要的,因为循环计数器甚至没有锁定在 /Od 中的寄存器中。性能影响不仅来自矢量化。
【解决方案3】:

尝试确保未设置 /arch 编译器选项。

【讨论】:

    【解决方案4】:

    哪个编译器? AFAIK,VS 将从版本 11 开始实现自动矢量化。VS 使用 SSE 指令进行浮点运算,但这并不意味着它实际上对循环进行了矢量化。

    【讨论】:

    • VC 2010。你的意思是我误解了“矢量化”这个词吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多