Visual Studio 2017循环自动向量化问题

Visual Studio 2017 loop auto-vectorization issue

本文关键字:向量化 问题 循环 Studio 2017 Visual      更新时间:2023-10-16

我正在尝试使用Visual C++2017自动矢量器对以下循环进行矢量化(/arch:AVX2(:

void fun(char* data, char* threshold, char* output, int64_t len)
{
// Assumes output filled with 0
for (int64_t c = 0, mm = len; c < mm; ++c)
{
output[c] = (data[c] < threshold[c])
? (threshold[c] - data[c]) 
: output[c];
}
}

该代码用于比较2个数组(数据和阈值(,并且如果数据<阈值,否则为0。

此循环不会自动向量化:

信息C5002:由于原因"1100",循环未矢量化

含义:循环包含控制流——例如;如果";或者"&";。

好的,我明白了,我需要重写我的循环,这样我就可以删除控制流,或者为编译器简化它。但是:

  • GCC对进行矢量化没有问题

  • 如果我以这种方式更改代码,Visual Studio接受对其进行矢量化:

代码:

for (int64_t c = 0, mm = len; c < mm; ++c)
{
output[c] = (data[c] < threshold[c])
? (char)(threshold[c] - data[c]) 
: output[c];
}

为什么这个(char(强制转换会更改Visual Studio自动矢量器的任何内容?这是自动矢量器的错误还是我遗漏了什么

此外,如果我将输出数组的类型从char更改为int,我就无法再让Visual Studio对我的循环进行矢量化,而GCC会:

void fun(char* data, char* threshold, int* output, int64_t len)
{
// Assumes output filled with 0
for (int64_t c = 0, mm = len; c < mm; ++c)
{
output[c] = (data[c] < threshold[c])
? (int)(threshold[c] - data[c]) 
: output[c];
}
}

与GCC相比,Visual Studio 2017自动矢量器是否不足?或者我是想做一些我不该做的事吗

这只是错过了一次优化机会。自2012年以来,VS矢量器已经改进了很多,但与gcc或clang相比,它仍然相当缺乏。请记住,他们的编译器是基于古老的代码库的,例如,直到最近,他们甚至没有SSA表示。