Avi*_*urg 7 c++ gcc trigonometry x86-64 vectorization
我在玩Compiler Explorer时遇到异常(我认为)。如果我想让编译器向量化一个sin计算,我会写:
#include <cmath>
#define NN 512
typedef float T;
typedef T __attribute__((aligned(NN))) AT;
inline T s(const T x)
{
return sinf(x);
}
void func(AT* __restrict x, AT* __restrict y, int length)
{
if (length & NN-1) __builtin_unreachable();
for (int i = 0; i < length; i++)
{
y[i] = s(x[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
用gcc 6.2编译-O3 -march=native -ffast-math并得到
#include <cmath>
#define NN 512
typedef float T;
typedef T __attribute__((aligned(NN))) AT;
inline T s(const T x)
{
return sinf(x);
}
void func(AT* __restrict x, AT* __restrict y, int length)
{
if (length & NN-1) __builtin_unreachable();
for (int i = 0; i < length; i++)
{
y[i] = s(x[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
#include <cmath>
#define NN 512
typedef float T;
typedef T __attribute__((aligned(NN))) AT;
inline T f(const T x)
{
return cosf(x)+sinf(x);
}
void func(AT* __restrict x, AT* __restrict y, int length)
{
if (length & NN-1) __builtin_unreachable();
for (int i = 0; i < length; i++)
{
y[i] = f(x[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
这使:
func(float*, float*, int):
testl %edx, %edx
jle .L10
leaq 8(%rsp), %r10
andq $-32, %rsp
pushq -8(%r10)
pushq %rbp
movq %rsp, %rbp
pushq %r14
xorl %r14d, %r14d
pushq %r13
leal -8(%rdx), %r13d
pushq %r12
shrl $3, %r13d
movq %rsi, %r12
pushq %r10
addl $1, %r13d
pushq %rbx
movq %rdi, %rbx
subq $8, %rsp
.L4:
vmovaps (%rbx), %ymm0
addl $1, %r14d
addq $32, %r12
addq $32, %rbx
call _ZGVcN8v_sinf // YAY! Vectorized trig!
vmovaps %ymm0, -32(%r12)
cmpl %r13d, %r14d
jb .L4
vzeroupper
addq $8, %rsp
popq %rbx
popq %r10
popq %r12
popq %r13
popq %r14
popq %rbp
leaq -8(%r10), %rsp
.L10:
ret
Run Code Online (Sandbox Code Playgroud)
我看到两个不错的选择。要么调用向量化版本sincosf或致电矢量sin和cos顺序。我尝试添加-fno-builtin-sincos无济于事。
这是gcc的已知问题吗?无论哪种方式,有没有一种方法可以说服gcc对后一个示例进行矢量化处理?
(顺便说一句,有没有办法让gcc <6自动对三角函数进行矢量化处理?)
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |