包含比较的循环的自动矢量化

时间:2017-07-27 01:47:04

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

我正在尝试使用Visual C ++ 2013自动矢量化器来进行以下循环矢量化(/arch:AVX2),但编译器拒绝并提供以下消息:

info C5002: loop not vectorized due to reason '1100'

reason code表示

Loop contains control flow—for example, "if" or "?".

我试图将比较和最终赋值拆分为一个单独的循环,但是当intrinsics可用于对浮点值进行比较时,这似乎效率低下。

为什么编译器会将比较视为流控制,我可以在实现中更改哪些内容以便编译器对该函数进行矢量化?

void triplets_positive(
    const std::uint64_t count,
    double * const a,
    double * const b,
    double * const c,
    std::uint64_t * const all_positive)
{
    for (std::uint64_t i = 0; i < count; ++i)
    {
        // These >= operations make the loop not vectorisable because
        // they introduce control flow.
        std::uint64_t a_pos = (a[i] >= 0.0);
        std::uint64_t b_pos = (b[i] >= 0.0);
        std::uint64_t c_pos = (c[i] >= 0.0);

        all_positive[i] = a_pos & b_pos & c_pos;
    }
}

1 个答案:

答案 0 :(得分:0)

不幸的是,这似乎是Visual C ++ 2013编译器中的错误或限制。其他编译器使用CMPPD指令(AVX / AVX2)或CMP*PD指令(SSE2)。

成功矢量化此循环的编译器包括:

  • Visual C ++ 2017
  • Visual C ++ 2015
  • Clang + LLVM(Apple LLVM version 8.1.0 (clang-802.0.42)

虽然理论上可以将比较写为按位运算,但这会适得其反,最好的选择是升级到另一个编译器。