为什么这个 C 向量循环不自动向量化?
Why doesn't this C vector loop auto-vectorise?
我正在尝试使用 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 版。
任何人都可以帮助我解释这些消息并了解发生了什么吗?
您已经使用内部函数手动向量化,因此 gcc 没有什么可以自动向量化的了。这会导致无趣的警告,我假设是因为尝试自动矢量化内部或循环计数器增量。
我从 gcc 5.3 (on the Godbolt compiler explorer) 得到了很好的 asm,如果我不做一些愚蠢的事情,比如写一个可以优化的函数,或者尝试只用 -O1
编译它。
#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 真正做什么的好方法。
我正在尝试使用 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 版。
任何人都可以帮助我解释这些消息并了解发生了什么吗?
您已经使用内部函数手动向量化,因此 gcc 没有什么可以自动向量化的了。这会导致无趣的警告,我假设是因为尝试自动矢量化内部或循环计数器增量。
我从 gcc 5.3 (on the Godbolt compiler explorer) 得到了很好的 asm,如果我不做一些愚蠢的事情,比如写一个可以优化的函数,或者尝试只用 -O1
编译它。
#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 真正做什么的好方法。