C:编写可以自动矢量化的代码,嵌套循环,GCC

时间:2013-02-13 16:07:05

标签: c gcc vectorization

我正在尝试编写一些可以进行矢量化的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]对任何内容进行矢量化。有没有办法重组它以便它可以?

1 个答案:

答案 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