gcc的自动向量化消息是什么意思?

4

我有一些需要快速运行的代码,因此我希望能说服gcc(g ++)对我的一些内部循环进行矢量化处理。我的编译器标志包括

-O3 -msse2 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=5

但是GCC无法将最重要的循环向量化,会给我以下不太详细的消息:

Not vectorized: complicated access pattern.

并且

Not vectorized: unsupported use in stmt.

我的问题是(1)这些究竟意味着什么?(在多么复杂之前才算太复杂?什么情况下使用不受支持?),以及(2)是否有任何方法可以让编译器给我更多关于我的错误的信息?
一个导致“复杂访问模式”的循环示例是:
for (int s=0;s<N;++s)
    a.grid[s][0][h-1] =  D[s] * (b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

在内部循环中出现“unsupported use in stmt”错误。

for (int s=0;s<N;++s)
    for (int i=1;i<w-1;++i) 
        for (int j=1;j<h-1;++j) 
            a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

(这是真正需要优化的部分。)在此,a.grid 和 b.grid 是三维浮点数数组,D 是一维浮点数数组,而 N、w 和 h 则为 const int。


这个问题 https://dev59.com/Tmsz5IYBdhLWcg3wDjpo 与此相关,但那里的答案非常特定于该人的特定问题,而我希望获得有关这些消息意义的更一般信息,所以我希望问另一个问题是否可以。 - N. Virgo
我能理解为什么第一个情况无法进行向量化。在第二个情况中,编译器会除了"unsupported use in stmt"之外再提供其他信息吗? - Mysticial
@Mysticial 如果您能看出第一个为什么无法向量化,请告诉我!(我不需要特别知道,但了解发生了什么情况会很好。)关于第二个问题,编译器没有提供比“在语句中使用不支持的内容”和行号更多的信息。 - N. Virgo
1
第一个情况涉及非顺序访问,因为s不是最低维度的索引。这通常会阻止矢量化。我对第二种情况一无所知。我肯定可以将第二种情况向量化。 - Mysticial
1个回答

3

未向量化:访问模式复杂。

“简单”的访问模式包括连续元素访问或带有某些限制的跨步元素访问(在循环中访问组的单个元素,组元素计数为2的幂,组大小为向量类型的倍数)。

b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

既非顺序访问也非跨步访问

未向量化:语句中使用不支持。

这里的“使用”是指数据流意义上的,获取变量(寄存器、编译器临时变量)的值。在这种情况下,“支持的使用”包括定义在循环当前迭代中的变量、常量和循环不变式。

a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

在这个例子中,我认为“不支持的使用”是因为b.grid[s][i][j-1]b.grid[s][i][j+1]被循环的前一次迭代所赋值(“定义”)了。

你忽略了我最初犯的同样错误。请注意第二个案例是完全不合适的(从b读取并写入a)。因此,所有迭代确实是独立的。 - Mysticial
是的,确实如此。事实上,GCC已经将该循环向量化了。也许在OP的情况下,编译器不知道a.gridb.grid不是别名?附:例如,如果它们被声明为struct S { float (*grid)[P][Q]; ... }; - chill
这是可能的,尽管我相信如果真的是这种情况,它会说一些关于可能的别名。+1 感谢指出 GCC 实际上确实这样做了。 - Mysticial
它们被声明为 struct S { float grid[N][w][h]; ... };。在我的代码上下文中,它们没有进行向量化处理。 - N. Virgo
a和b都在同一个cpp文件的全局作用域中声明,如果这有所不同。 - N. Virgo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接