为什么这个C矢量循环不能自动矢量化?

时间:2016-07-28 11:21:26

标签: c vectorization avx2

我正在尝试使用AVX内在函数优化某些代码。一个非常简单的测试用例编译,但告诉我,由于我不理解的一些原因,我的循环没有被矢量化。

这是完整的程序,simple.c

#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <immintrin.h>

int main(void)
{

  __m256 * x = (__m256 *) calloc(1024,sizeof(__m256));    

  for (int j=0;j<32;j++)
    x[j] = _mm256_set1_ps(1.); 

  return(0);
}

这是命令行: gcc simple.c -O1 -fopenmp -ffast-math -lm -mavx2 -ftree-vectorize -fopt-info-vec-missed

这是输出:

  • simple.c:11:3:注意:未矢量化:不支持的数据类型
  • simple.c:11:3:注意:无法确定矢量化因子。
  • simple.c:6:5:注意:没有矢量化:基本块中没有足够的数据引用。
  • simple.c:11:3:注意:没有矢量化:基本块中没有足够的数据引用。
  • simple.c:6:5:注意:没有矢量化:基本块中没有足够的数据引用。
  • simple.c:6:5:注意:没有矢量化:基本块中没有足够的数据引用。

我有gcc版本5.4。

任何人都可以帮我解释这些消息并了解发生了什么吗?

1 个答案:

答案 0 :(得分:3)

您已经使用内在函数手动进行矢量化,因此gcc无需自动向量化。这导致了无趣的警告,我假设尝试自动向量化内在或循环计数器增量。

我从gcc 5.3(on the Godbolt compiler explorer)得到了很好的asm,如果我不做一些愚蠢的事情,比如编写一个可以优化掉的函数,或者尝试仅用-O1编译它。 / p>

#include <immintrin.h>

void set_to_1(__m256 * x) {
  for (int j=0;j<32;j++)
    x[j] = _mm256_set1_ps(1.); 
}

    push    rbp
    lea     rax, [rdi+1024]
    vmovaps ymm0, YMMWORD PTR .LC0[rip]
    mov     rbp, rsp
    push    r10                      # gcc is weird with r10 in functions with ymm vectors
.L2:                                 # this is the vector loop
    vmovaps YMMWORD PTR [rdi], ymm0
    add     rdi, 32
    cmp     rdi, rax
    jne     .L2
    vzeroupper
    pop     r10
    pop     rbp
    ret

.LC0:
    .long   1065353216
    ... repeated several times because gcc failed to use a vbroadcastss load or generate the constant on the fly

我实际上从-O1获得了几乎相同的asm,但使用-O1来优化事物并不是了解gcc真正做什么的好方法。