我有一些我希望快速运行的代码,所以我希望我能说服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是常数
答案 0 :(得分:3)
未矢量化:复杂的访问模式。
“简单”访问模式是具有某些限制的连续元素访问或跨步元素访问(在循环中访问的组的单个元素,组元素计数是2的幂,组大小是向量类型的倍数)。
b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);
无论是顺序访问还是跨步访问
未向量化:在stmt中不支持使用。
这里“use”是数据流意义上的,获取变量的值(寄存器,编译器临时)。在这种情况下,“支持的用途”是变量,在循环的当前迭代,常量和循环不变量中定义。
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]
被循环的前一次迭代赋值(“定义”)。