Loops 如何将循环矢量化?哪些向量操作可以通过循环实现

Loops 如何将循环矢量化?哪些向量操作可以通过循环实现,loops,vectorization,Loops,Vectorization,你能给我举个循环如何矢量化的例子吗?例如,我有以下循环: for (i=1; i < N; i++) { a[i] = b[i]*c[i]; d[i] = a[i-1] + 7; } (i=1;i

你能给我举个循环如何矢量化的例子吗?例如,我有以下循环:

for (i=1; i < N; i++) {
     a[i] = b[i]*c[i];
     d[i] = a[i-1] + 7;
}
(i=1;i{ a[i]=b[i]*c[i]; d[i]=a[i-1]+7; }
我知道在对循环进行矢量化之前不应该有任何依赖关系,但是在显示没有依赖关系之后会发生什么呢。如何准确地对其进行矢量化,采取什么步骤?

从您的问题来看,我不太清楚您是问如何手动对其进行矢量化,还是问矢量化编译器是如何做到这一点的。所以我只想解释一下编译器是如何做到这一点的,如果你愿意,你可以随时手动重复同样的步骤。让我们以将矢量化为宽度4为例

原始代码:

for (i=1; i < N; i++) {
  a[i] = b[i]*c[i];
  d[i] = a[i-1] + 7;
}
这两个现在都可以矢量化;让我们关注第一个,但另一个也一样。所以我们的代码是:

for (i=1; i < N; i++) {
  a[i] = b[i]*c[i];
}
(i=1;i{ a[i]=b[i]*c[i]; } 对于我们的示例,假设矢量化宽度为4。矢量化的关键是。因此编译器展开到大小4:

int i = 1;
// Unrolled loop:
for (; i < N-3; i+=4) {
  a[i]   = b[i]  *c[i];
  a[i+1] = b[i+1]*c[i+1];
  a[i+2] = b[i+2]*c[i+2];
  a[i+3] = b[i+3]*c[i+3];
}
// Remainder loop:
for (; i < N; i++) {
  a[i] = b[i]*c[i];
}
inti=1;
//展开循环:
对于(;i
现在很明显,如何矢量化-编译器将展开循环中相同的指令序列3更改为单个矢量指令:

int i = 1;
// Unrolled loop:
for (; i < N-3; i+=4) {
  a[i:i+3] = b[i:i+3]*c[i:i+3];
}
// Remainder loop:
for (; i < N; i++) {
  a[i] = b[i]*c[i];
}
inti=1;
//展开循环:
对于(;i
稍后,在编译器的后期“降低”阶段,它将为该操作分配一条实际指令——例如,如果这些是支持SSE的体系结构上的单精度浮点数组,它可能会使用

1当然是以简化的方式。
2请记住,在这种情况下,循环裂变实际上会损害数据的局部性。
3编译器实际上不必展开,只需查找重复项-这些步骤通常一起进行。

这是什么语言?这可能是显而易见的,但你仍然应该在你的问题中详细说明。这是错误的。假设i=0,那么您正在设置a[11]=b[0]*c[0],但下一个语句您希望将d[0]设置为[4*N]+7,显然,[4*N]可能尚未初始化/分配。因此,必须首先解决这个数据依赖关系。@Jubobs和DebasishJana,尽管没有指定语言,并且给出的示例不是最好的,但我仍然想尝试了解向量化的进一步步骤。或者,您可以给出自己的示例,并展示如何在假设不存在依赖性的情况下实现。如果你问一种特定的语言,我觉得这个问题要么太广泛,要么太不清楚(或者两者都不清楚),不适合堆栈溢出。请看@Jubobs,比如说在Conly thing中,我不明白您为什么要输入以下代码
//余数循环:对于(;i
@Mikon展开循环时,需要创建一个余数循环,以处理迭代次数不能被展开宽度整除的情况。
int i = 1;
// Unrolled loop:
for (; i < N-3; i+=4) {
  a[i:i+3] = b[i:i+3]*c[i:i+3];
}
// Remainder loop:
for (; i < N; i++) {
  a[i] = b[i]*c[i];
}