我正在尝试编写一些可以进行矢量化的C代码。这是我正在尝试的循环:
for(jj=0;jj<params.nx;jj++)
for(kk=0;kk<NSPEEDS;kk++)
local_density_vec[jj] += tmp_cells_chunk[jj].speeds[kk];
GCC在使用-ftree-vectorizer-verbose=5
标记http://pastebin.com/RfCc04aS运行时给出了以下消息。
如何重写它以便可以自动矢量化。 NSPEEDS
是5。
编辑:
我继续努力,我似乎无法使用.speeds[kk]
对任何内容进行矢量化。有没有办法重组它以便它可以?
答案 0 :(得分:3)
for (jj = 0; jj < nx; jj++) {
partial = 0.0f;
fp = c[jj].speeds;
for (kk = 0; kk < M; kk++)
partial += fp[kk];
out[jj] = partial;
}
(...)
Calculated minimum iters for profitability: 12
36: Profitability threshold = 11
Vectorizing loop at autovect.c:36
36: Profitability threshold is 11 loop iterations.
36: LOOP VECTORIZED.
重点:
1)在转储中,循环被认为是“复杂的访问模式”(请参阅日志的最后一行)。正如已经评论过的,这与编译器无法验证别名有关。对于“简单”访问模式,请参阅: http://gcc.gnu.org/projects/tree-ssa/vectorization.html#vectorizab
2)我的示例循环需要12次迭代才能使矢量化变得有用。由于NSPEEDS == 5,如果编译器向你量化,编译器将会失去时间。
3)在添加-funsafe-math-optimizations后,我只能对我的循环进行矢量化。我认为这是必需的,因为与得到的向量运算有不同的舍入或相关性行为。例如,见: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
4)如果你反转循环,你可能会再次遇到“复杂”访问模式的问题。如前所述,您可能需要反转阵列组织。检查有关跨步访问的gcc矢量化文档,检查是否可以匹配其中一种模式。
为了完整起见,这是完整的例子: http://pastebin.com/CWhyqUny