C 如何对循环进行矢量化?

C 如何对循环进行矢量化?,c,optimization,parallel-processing,vectorization,cluster-computing,C,Optimization,Parallel Processing,Vectorization,Cluster Computing,我在对循环进行矢量化时遇到问题。我希望重写下面的代码,使其矢量化。我已经完成了Banerjee的测试,我发现所有的依赖关系都被破坏了,但我不知道从这里可以走到哪里。 编译器是gcc。架构为x86,阵列为整数阵列 for (int i = 0; i < 100; i++) { x[20 + i] = y[i] * z[i]; p[i] = x[21 + i] + q[i]; } for(inti=0;i

我在对循环进行矢量化时遇到问题。我希望重写下面的代码,使其矢量化。我已经完成了Banerjee的测试,我发现所有的依赖关系都被破坏了,但我不知道从这里可以走到哪里。 编译器是gcc。架构为x86,阵列为整数阵列

for (int i = 0; i < 100; i++) { 
     x[20 + i] = y[i] * z[i];
     p[i] = x[21 + i] + q[i];
}
for(inti=0;i<100;i++){
x[20+i]=y[i]*z[i];
p[i]=x[21+i]+q[i];
}
两个一般提示:

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

  • 虽然循环第二行上的从
    x
    读取并不依赖于第一行上的写入,但编译器可能不够聪明,无法检测到这一点。通过交换这两行代码,或者在写之前将读操作移动到自己的循环中,来帮助解决这个问题

gcc 10.2使用
-O3-march skylake
()成功地对以下版本进行了矢量化,使用ymm寄存器每次迭代处理8
int
s。它还完全展开循环,因为迭代计数是恒定的,不会太大

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];
    }
}
void foo(
int*x,
常数int*y,
常数int*z,
int*p,
常数int*限制q
) {
对于(int i=0;i<100;i++){
p[i]=x[21+i]+q[i];
x[20+i]=y[i]*z[i];
}
}

矢量化通常是一种优化,您需要依靠编译器来执行。C语言没有一种表达“这个循环应该矢量化”的方法,尽管它可能是您的特定实现提供了一个用于此目的的扩展。例如:
gcc-ftree vectorize…
您能澄清一下您的意思吗?您是在问使用什么编译器开关来要求编译器进行向量化(您没有说您正在使用什么编译器),还是要对代码进行什么更改以鼓励编译器有效地进行向量化(仍然依赖于编译器),或者如何使用向量指令自己用汇编语言重写代码(您没有说什么CPU)?无论如何,需要更多的信息。@NateEldredge我的道歉。我的意思是如何用C语言重写,使其矢量化。我现在就要编辑了!还有,为什么要使用和标签?这些通常是指将计算划分为多个线程/进程/作业,然后这些线程/进程/作业可以在多个内核/CPU/计算机上并行运行。但矢量化将计算保持在单个核上的单个线程中,只要求该核使用同时处理多个数据元素的指令。