4

我正在尝试编写一些可以矢量化的 C 代码。这是我正在尝试的循环:

for(jj=0;jj<params.nx;jj++)
    for(kk=0;kk<NSPEEDS;kk++)
        local_density_vec[jj] += tmp_cells_chunk[jj].speeds[kk];

-ftree-vectorizer-verbose=5当使用标志http://pastebin.com/RfCc04aS运行时,GCC 会给我以下消息。

我怎样才能重写它以便它可以自动矢量化。NSPEEDS是 5。

编辑:

我一直在努力,我似乎​​无法用.speeds[kk]. 有没有办法对其进行重组以使其可以?

4

1 回答 1

4
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

于 2013-02-13T20:15:11.923 回答