【问题标题】:What do gcc's auto-vectorization messages mean?gcc 的自动矢量化消息是什么意思?
【发布时间】:2012-11-10 10:16:20
【问题描述】:

我有一些我想快速运行的代码,所以我希望我能说服 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]);

其中一个给出“在 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 ints .

【问题讨论】:

  • 这个问题stackoverflow.com/questions/8144191/… 是相关的,但那里的答案非常具体到那个人的特定问题,而我希望能获得更多关于这些消息含义的一般信息,所以我希望没问题问另一个问题。
  • 我明白为什么第一种情况没有矢量化。在第二种情况下,除了"unsupported use in stmt"之外,编译器还会给出更多信息吗?
  • @Mysticial 如果你能明白为什么第一个没有矢量化,请赐教! (我不需要,特别是,但很高兴知道发生了什么。)关于第二个,不,编译器没有提供比“stmt 中不支持的使用”和行号更多的信息。跨度>
  • 第一种情况涉及非顺序访问,因为s 不是最低维度的索引。仅此一项通常会阻止矢量化。我不知道第二种情况。我当然可以矢量化第二种情况。
  • @Mystical 非常感谢,我不知道。

标签: c++ gcc compiler-optimization vectorization


【解决方案1】:

未矢量化:复杂的访问模式。

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

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

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

未矢量化:在 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] 是由循环的先前迭代分配(“定义”)的。

【讨论】:

  • 你忽略了我最初做的同样的事情。请注意,第二种情况完全不合时宜。 (从b 读取并写入a。)所以所有的迭代确实是独立的。
  • 是的,确实如此。事实上,这个循环是由 GCC 向量化的。也许在 OP 的情况下,编译器不知道 a.gridb.grid 没有别名? PS。例如如果它们被声明为struct S { float (*grid)[P][Q]; ... };
  • 这是可能的,尽管我相信如果确实如此,它会说明可能的混叠。 +1 指出 GCC 确实做到了。
  • 它们被声明为struct S { float grid[N][w][h]; ... };。在我的代码上下文中,它们不是矢量化的。
  • a 和 b 都在同一个 cpp 文件的全局范围内声明,如果有区别的话。
猜你喜欢
  • 2010-12-03
  • 2014-05-06
  • 1970-01-01
  • 2018-12-16
  • 2021-12-26
  • 2016-02-18
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多