C++ 如何让gcc完全矢量化这个sqrt循环?
如果我接受这个密码C++ 如何让gcc完全矢量化这个sqrt循环?,c++,gcc,x86,icc,auto-vectorization,C++,Gcc,X86,Icc,Auto Vectorization,如果我接受这个密码 #包括 void compute_sqrt(常数double*x,double*y,int n){ int i; #pragma omp simd线性(i) 对于(i=0;i如果添加-ffast math标志,gcc将使用YMM寄存器,例如: vsqrtpd (%rdi,%rax), %ymm0 vmovupd %ymm0, (%rcx,%rax) XMM是128位寄存器 更糟糕的是,vsqrtsd甚至不是一个向量运算,如末尾的sd所示(标量,双精度)。XMM寄存器也被类
#包括
void compute_sqrt(常数double*x,double*y,int n){
int i;
#pragma omp simd线性(i)
对于(i=0;i如果添加-ffast math
标志,gcc将使用YMM寄存器,例如:
vsqrtpd (%rdi,%rax), %ymm0
vmovupd %ymm0, (%rcx,%rax)
XMM是128位寄存器
更糟糕的是,vsqrtsd
甚至不是一个向量运算,如末尾的sd
所示(标量,双精度)。XMM寄存器也被类似的标量浮点运算使用,但只有寄存器的低位64或32位包含有用的数据,其余的被调零
缺少的选项有-fno math errno
(此标志也由-ffast math
暗示,具有附加效果)和(可选)-mprefere vector width=512
-fno math errno
关闭数学运算的设置errno
,特别是对于平方根,这意味着NaN中的负输入结果没有设置errno
到EDOM
。默认情况下,ICC显然不关心这一点
-mpreferevector width=512
使自动矢量化在有意义时更倾向于512位操作。默认情况下,首选256位操作,至少对于cascadelake
和skylake-avx512
和其他当前处理器而言,对于所有未来的处理器来说可能不会保持这种方式。ICC默认为-fp model fast=1
,有点像gcc/clang-ffast math
,包括我认为将FP math视为关联。因此,是的,默认情况下,ICC在设置errno
方面不太在意。这就是为什么OP使用vrsqrt14pd
,一种快速近似倒数。请注意vrsqrt14pd
是一种快速近似值倒数,是sqrt近似值的一部分,如果这是循环中的所有操作(如代码),则速度更快。在现实生活中,将sqrt作为其他计算的一部分,以便它可以与其他活动的ALU重叠。
...
vsqrtpd 32(%rdi,%r9,8), %ymm1 #7.12
...
...
vrsqrt14pd %zmm4, %zmm1 #7.12
...
vsqrtpd (%rdi,%rax), %ymm0
vmovupd %ymm0, (%rcx,%rax)