C++ gcc';s的自动矢量化消息意味着什么?

C++ gcc';s的自动矢量化消息意味着什么?,c++,gcc,compiler-optimization,vectorization,C++,Gcc,Compiler Optimization,Vectorization,我有一些我想快速运行的代码,所以我希望能说服gcc(g++)对我的一些内部循环进行矢量化。我的编译器标志包括 -O3 -msse2 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=5 但gcc无法对最重要的循环进行矢量化,这给了我以下一条并不十分详细的消息: Not vectorized: complicated access pattern. 及 我的问题是(1)这些到底意味着什么?(在它变得太复杂之前,它必须有多复杂?不支持使

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

-O3 -msse2 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=5
但gcc无法对最重要的循环进行矢量化,这给了我以下一条并不十分详细的消息:

Not vectorized: complicated access pattern.

我的问题是(1)这些到底意味着什么?(在它变得太复杂之前,它必须有多复杂?不支持使用什么?)和(2)有没有办法让编译器给我更多一点点关于我做错了什么的信息

给出“复杂访问模式”的循环示例如下

for(int s=0;s)
未矢量化:复杂的访问模式

“简单”访问模式是具有特定限制的连续元素访问或跨步元素访问(循环中访问的组的单个元素,组元素计数为2的幂,组大小为向量类型的倍数)

既不是顺序访问,也不是跨步访问

未矢量化:不支持在stmt中使用

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

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]
通过循环的上一次迭代。

这个问题是相关的,但答案非常具体地针对那个人的特定问题,而我希望获得关于这些消息的含义的一些更一般的信息,所以我希望可以问另一个问题。我可以理解为什么第一种情况没有矢量化。在第二种情况下,compiler除了“stmt中不支持的使用”之外,还提供了更多的信息。
?@Mystical如果你能理解为什么第一个没有矢量化,请告诉我!(我不需要特别说明,但很高兴知道发生了什么。)关于第二个问题,不,编译器没有提供比“stmt中不支持的使用”更多的信息还有行号。第一种情况涉及非顺序访问,因为
s
不是最低维度的索引。仅此一种情况通常会阻止矢量化。我不知道第二种情况。我当然可以矢量化第二种情况。@非常感谢,我不知道。你忽略了我最初忽略的同一件事注意,第二种情况完全不合适。(从
b
读取并写入
a
)所以所有的迭代都是独立的。是的,确实如此。事实上,这个循环是由GCC矢量化的。也许在OP的情况下,编译器不知道
a.grid
b.grid
没有别名?PS。例如,如果它们被声明为
struct S{float(*grid)[P][Q];}
这是可能的,尽管我相信它会说明一些可能的别名,如果真的是这样的话。+1指出GCC确实做到了这一点。它们被声明为
struct s{float grid[N][w][h];…};
。在我的代码上下文中,它们不是矢量化的。a和b都在同一cpp文件的全局范围内声明,如果这有区别的话。
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]);
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]);
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]);