【问题标题】:C: Writing code which can be auto vectorized, nested loop, GCCC:编写可以自动矢量化、嵌套循环、GCC 的代码
【发布时间】:2013-01-29 05:56:34
【问题描述】:

我正在尝试编写一些可以向量化的 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] 对任何东西进行矢量化处理。有没有办法对其进行重组以使其可以?

【问题讨论】:

  • 编译器无法对其进行矢量化处理,因为它无法确定数组之间是否存在别名。此外,您的 NSPEEDS 行程计数太小,无法从矢量化中获得任何加速。
  • 在我的第一次尝试中,我交换了循环。我希望它用NSPEEDS 展开外观并矢量化另一个循环。任何带有.speeds[kk] 的循环都无法矢量化。我可以改变这个吗?
  • 在这种情况下别名是什么意思?
  • 别名意味着编译器不知道你的数组是否重叠。矢量化通常会改变访问内存的顺序。编译器不能合法地向量化,除非它可以证明它不会违反任何依赖关系。
  • 简而言之,无论您如何订购,您的代码都无法矢量化。向量化通常只适用于顺序和连续的内存访问。无论您如何订购循环,这里都不是这种情况。问题是tmp_cells_chunk 似乎是一个结构。这意味着您有array-of-structs 包装。如果要矢量化,可能必须切换到 struct-of-arrays 内存布局。

标签: c gcc vectorization


【解决方案1】:
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

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 2019-04-12
    • 2015-11-01
    • 2011-12-29
    • 2019-04-05
    相关资源
    最近更新 更多