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

Auto-vectorization of loop containing comparisons

本文关键字:矢量化 循环 比较 包含      更新时间:2023-10-16

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

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

此原因码表示

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

我试图将比较和最终赋值拆分到一个单独的循环中,但是当有可用于对浮点值执行比较的内部函数时,这似乎效率低下。

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

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;
}
}

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

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

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

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