为什么GCC不会自动矢量化这个循环?

Jer*_*wen 5 c gcc vectorization

我有以下C程序(我的实际用例的简化,表现出相同的行为)

#include <stdlib.h>
#include <math.h>
int main(int argc, char ** argv) {
    const float * __restrict__ const input = malloc(20000*sizeof(float));
    float * __restrict__ const output = malloc(20000*sizeof(float));

    unsigned int pos=0;
    while(1) {
            unsigned int rest=100;
            for(unsigned int i=pos;i<pos+rest; i++) {
                    output[i] = input[i] * 0.1;
            }

            pos+=rest;            
            if(pos>10000) {
                    break;
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我编译时

 -O3 -g -Wall -ftree-vectorizer-verbose=5 -msse -msse2 -msse3 -march=native -mtune=native --std=c99 -fPIC -ffast-math
Run Code Online (Sandbox Code Playgroud)

我得到了输出

main.c:10: note: not vectorized: unhandled data-ref 
Run Code Online (Sandbox Code Playgroud)

其中10是内部for循环的行.当我查找为什么它可能会这样说时,它似乎是说指针可能是别名,但它们不能在我的代码中,因为我有__restrict关键字.他们还建议包括-msse标志,但它们似乎也没有做任何事情.有帮助吗?

caf*_*caf 3

这确实看起来像一个错误。在下面的内容中,等效函数foo()已矢量化,但bar()在针对 x86-64 目标进行编译时则未矢量化:

void foo(const float * restrict input, float * restrict output)
{
    unsigned int pos;
    for (pos = 0; pos < 10100; pos++)
        output[pos] = input[pos] * 0.1;
}

void bar(const float * restrict input, float * restrict output)
{
    unsigned int pos;
    unsigned int i;
    for (pos = 0; pos <= 10000; pos += 100)
        for (i = 0; i < 100; i++)
            output[pos + i] = input[pos + i] * 0.1;
}
Run Code Online (Sandbox Code Playgroud)

添加该-m32标志来编译 x86 目标会导致两个函数都被矢量化。