我想让我的代码由编译器自动矢量化,但似乎无法正确处理。
特别是我从中收到的带有-ftree-vectorizer-verbose=6
的消息
选项为125: not vectorized: not suitable for gather D.32476_34 = *D.32475_33;
。
现在我的问题是,此消息表示什么意思,这些数字代表什么?
贝娄,我创建了一个简单的测试示例,该示例产生了相同的消息,
所以我认为这些问题将是相关的。
static void not_suitable_for_gather(unsigned char * __restrict__ pixels, int * __restrict__ indices, int indices_num)
{
for (int i = 0; i < indices_num; ++i)
{
int idx = indices[i] * 4;
float r = pixels[idx + 0];
float g = pixels[idx + 1];
float b = pixels[idx + 2];
float a = pixels[idx + 3] / 255.0f;
pixels[idx + 0] = r;
pixels[idx + 1] = g;
pixels[idx + 2] = b;
pixels[idx + 3] = a * 255.0f;
}
return;
}
另外,在创建示例时,我遇到了很多其他信息,
我不是很确定他们的意思,或者为什么会特定的结构
矢量化存在问题,是否有任何指南,书籍,教程,博客等
那会向我解释这些事情吗?
如果那很重要,我将在QtCreator 2.7.0中使用MingW 4.7 32位。
编辑:结论:
根据我对这篇文章的测试和建议,该消息最有可能与通过辅助索引数组间接访问数据有关,这导致gather/scatter addressing scheme,并且目前
GCC
无法(或不希望)对其进行矢量化处理。我能够使用clang++ 3.2-1
生成矢量化代码。 最佳答案
代码的矢量化版本在概念上看起来像(使用OpenCL语法):
for (int i = 0; i < indices_num; ++i)
{
int idx = indices[i] * 4;
float4 factor = (1, 1, 1, 255.0f);
char4 x1 = vload4(idx, pixels); // Line A
float4 x2 = convert_float4(x1);
float4 x3 = x2 / factor;
float4 x4 = x3 * factor;
char4 x5 = convert_char4(x4);
vstore4(x5, idx, pixels); // Line B
}
但是等一下;在A行中,您尝试从内存中加载四个 chars (aka uint8),并将它们存储在B行中。我所知道的唯一支持该功能的指令集是启用AVX2(Intel Haswells及更高版本)和Xeon Phi的。除非您要编译其中之一,否则可以解释为什么您的编译器会拒绝这种矢量化机会。
当然,编译器可以分别加载4个uint8,从它们构建 vector ,执行所需的 vector 运算,然后手动存储4个值。但是我猜想,与通过向量化节省的实际工作量相比,没有聚集和分散的情况,单独加载和存储值可能被认为过于昂贵。
关于c++ - 未向量化: not suitable for gather D. 32476_34 = * D.32475_33;,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17567029/