AVX 内在函数 _mm256_rsqrt_ps 的相对误差比根据内在函数指南应有的要大得多

jon*_*cho 2 c++ floating-point intrinsics avx

英特尔内在函数指南指出,内在函数_mm256_rsqrt_ps的相对误差最多为1.5*2^-12。但是,当我将 的结果_mm256_rsqrt_ps与平方根倒数 ( 1.0 / sqrt(x)) 的标准 C++ 计算结果进行比较时,我得到的相对误差远大于1.5*2^-12

我使用以下程序来测试这一点:

#include <immintrin.h>
#include <iostream>
#include <math.h>

void test(float x) {
  float resP = _mm256_cvtss_f32(_mm256_rsqrt_ps(_mm256_set1_ps(x)));
  float res = 1.0 / sqrt(x);
  float relErr = fabs(resP - res) / res;
  std::cout << "x = " << x << std::endl;
  std::cout << "resP = " << resP << std::endl;
  std::cout << "res = " << res << std::endl;
  std::cout << "relErr = " << relErr << std::endl;
}

int main() {
  test(1e30);
  test(1e-30);
  test(1e17);
  test(1e-17);
}
Run Code Online (Sandbox Code Playgroud)

它输出以下内容:

#include <immintrin.h>
#include <iostream>
#include <math.h>

void test(float x) {
  float resP = _mm256_cvtss_f32(_mm256_rsqrt_ps(_mm256_set1_ps(x)));
  float res = 1.0 / sqrt(x);
  float relErr = fabs(resP - res) / res;
  std::cout << "x = " << x << std::endl;
  std::cout << "resP = " << resP << std::endl;
  std::cout << "res = " << res << std::endl;
  std::cout << "relErr = " << relErr << std::endl;
}

int main() {
  test(1e30);
  test(1e-30);
  test(1e17);
  test(1e-17);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,相对误差明显大于1.5*2^-12

该指令的_mm256_rcp_ps相对误差似乎也比内在函数指南所说的大得多。

难道我做错了什么?我是否误解了内在指南?或者内在函数指南是错误的?

Unl*_*kus 9

你的相对误差范围内。

1.5*2^-12 = 0.000366

它只是2的幂而不是10的幂。

此外,它并不声称与单精度 1/sqrt(x) 相比有这种相对误差,而是与精确结果相比。