你如何矢量化一个循环?

Mr.*_*oom 5 c parallel-processing optimization cluster-computing vectorization

我在矢量化循环时遇到了麻烦。我正在寻找重写下面的代码,使其矢量化。我已经运行了 Complete Banerjee 的测试,我发现所有依赖项都被破坏了,但我不知道从哪里开始。编译器是gcc。体系结构是 x86,数组是整数数组。

for (int i = 0; i < 100; i++) { 
     x[20 + i] = y[i] * z[i];
     p[i] = x[21 + i] + q[i];
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*dge 3

两个一般提示:

  • 将数组作为参数传递给函数,使用restrict关键字通知编译器它们不能互相别名(这将阻止任何向量化)。

  • 尽管循环第二行的读取x不依赖于第一行的写入,但编译器可能不够智能,无法检测到这一点。通过交换这两行或者在写入之前将读取移动到其自己的循环来帮助它。

以下版本由 gcc 10.2 成功矢量化-O3 -march-skylake尝试使用 Godbolt),使用 ymm 寄存器每次迭代处理 8int秒。它还完全展开循环,因为迭代计数是恒定的并且不是太大。

void foo(
            int *restrict x,
            const int *restrict y,
            const int *restrict z,
            int *restrict p,
            const int *restrict q
        ) {
    for (int i = 0; i < 100; i++) { 
        p[i] = x[21 + i] + q[i];
        x[20 + i] = y[i] * z[i];
    }
}
Run Code Online (Sandbox Code Playgroud)