如果我取了这个密码
#include <cmath>
void compute_sqrt(const double* x, double* y, int n) {
int i;
#pragma omp simd linear(i)
for (i=0; i<n; ++i) {
y[i] = std::sqrt(x[i]);
}
}
然后用g++ -S -c -O3 -fopenmp-simd -march=cascadelake
编译,然后在循环中得到这样的指令(编译器资源管理器)
...
vsqrtsd %xmm0, %xmm0, %xmm0
...
XMMs是128位寄存器,但是级联寄存器支持avx-512。有没有办法让gcc使用256 (YMM)或512位(ZMM)寄存器?
相比之下,ICC默认使用256个寄存器作为级联:使用icc -c -S -O3 -march=cascadelake -qopenmp-simd
produces (编译器资源管理器)编译。
...
vsqrtpd 32(%rdi,%r9,8), %ymm1 #7.12
...
您还可以添加选项-qopt-zmm-usage=high
来使用512位寄存器(编译器资源管理器)。
...
vrsqrt14pd %zmm4, %zmm1 #7.12
...
发布于 2020-08-23 00:26:59
XMM是128位寄存器。
更糟糕的是,vsqrtsd
甚至不是向量操作,正如sd
在末尾所指出的那样(标量,双精度)。像这样的标量浮点操作也使用XMM寄存器,但是只有低64或32位的寄存器包含有用的数据,其余的则为零。
缺少的选项是-fno-math-errno
( -ffast-math
也暗示了这个标志,它有附加的效果)和(可选) -mprefer-vector-width=512
。
-fno-math-errno
关闭数学操作的errno
设置,特别是对于平方根--这意味着NaN中的负值输入结果,而不将errno
设置为EDOM
。在默认情况下,国际刑事法院显然不关心这一点。
-mprefer-vector-width=512
使自动矢量化在有意义时更喜欢512位操作。默认情况下,256位操作是首选的,至少对于cascadelake
和skylake-avx512
以及其他当前处理器来说,它可能不会在未来的所有处理器上保持这种状态。
发布于 2020-08-23 00:20:24
https://stackoverflow.com/questions/63542208
复制相似问题