矢量化失败了GCC

jaa*_*aap 3 c c++ gcc vectorization icc

我试图理解矢量化,但令我惊讶的是这个非常简单的代码没有被矢量化

#define n 1024
int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];
}
Run Code Online (Sandbox Code Playgroud)

虽然英特尔编译器由于某种原因导致初始化循环,第5行.

> icc -vec-report a.c
a.c(5): (col. 3) remark: LOOP WAS VECTORIZED
Run Code Online (Sandbox Code Playgroud)

有了海湾合作委员会,我似乎一无所获

> gcc -ftree-vectorize -ftree-vectorizer-verbose=2 a.c
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?这不应该是一个非常简单的可矢量化循环吗?所有相同的操作,连续存储器等.我的CPU支持SSE1/2/3/4.

--- 更新 ---

根据下面的答案,这个例子对我有用.

#include <stdio.h>
#define n 1024

int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];

  printf("%d\n", c[1023]);  
}
Run Code Online (Sandbox Code Playgroud)

用icc

> icc -vec-report a.c
a.c(7): (col. 3) remark: LOOP WAS VECTORIZED
a.c(8): (col. 3) remark: LOOP WAS VECTORIZED
Run Code Online (Sandbox Code Playgroud)

和gcc

> gcc -ftree-vectorize -fopt-info-vec -O a.c
a.c:8:3: note: loop vectorized
a.c:7:3: note: loop vectorized
Run Code Online (Sandbox Code Playgroud)

man*_*lio 8

我稍微修改了你的源代码,以确保GCC无法删除循环:

#include <stdio.h>
#define n 1024

int main () {
  int i, a[n], b[n], c[n];

  for(i=0; i<n; i++) { a[i] = i; b[i] = i*i; }
  for(i=0; i<n; i++) c[i] = a[i]+b[i];

  printf("%d\n", c[1023]);  
}
Run Code Online (Sandbox Code Playgroud)

GCC(v4.8.2)可以对两个循环进行向量化,但它需要-O标志:

gcc -ftree-vectorize -ftree-vectorizer-verbose=1 -O2 a.c
Run Code Online (Sandbox Code Playgroud)

我得到:

在ac:8处分析循环

在ac:8处矢量化循环

ac:8注意:LOOP VECTORIZED.在ac:7处分析循环

在ac:7处矢量化循环

ac:7注意:LOOP VECTORIZED.ac:注意:函数中的矢量化2个循环.

使用-fdump-tree-vect开关GCC会在a.c.##t.vect文件中转储更多信息(了解"内部"发生的事情非常有用).

还要考虑:

  • 请注意,编译器仍然可以删除循环,因为它可以在编译期间运行循环,替换结果. (2认同)