为什么 g++ -O3 不将除法改为乘法?

Why doesn't g++ -O3 change division to multiplication?

本文关键字:除法 g++ -O3 为什么      更新时间:2023-10-16

我以为g -o3会自动更改为乘法。但要累积此代码:

#include <iostream>
#include <sys/time.h>
double compute0(int i) {
  double d_2 = i * i; 
  double ret = 0;
  for (int j = 0; j < 1000000; j++) {
    ret += j;
  }
  return ret;
}
double compute1(int i) {
  double d_2 = i * i; 
  double ret = 0;
  for (int j = 0; j < 1000000; j++) {
    ret += j / d_2;
  }
  return ret;
}
double compute2(int i) {
  double d_2 = i * i; 
  double d_2_inv = 1.0 / d_2; 
  double ret = 0;
  for (int j = 0; j < 1000000; j++) {
    ret += j * d_2_inv;
  }
  return ret;
}
double tik() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return tv.tv_sec + tv.tv_usec * 1e-6;
}
int main() {
  {
    double begin = tik();
    double ret = 0;
    for(int i = 1; i < 100; i++)
      ret += compute0(i);
    double end = tik();
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
  }
  {
    double begin = tik();
    double ret = 0;
    for(int i = 1; i < 100; i++)
      ret += compute1(i);
    double end = tik();
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
  }
  {
    double begin = tik();
    double ret = 0;
    for(int i = 1; i < 100; i++)
      ret += compute2(i);
    double end = tik();
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
  }
  return 0;
}

输出为:

成本时间:0.105436 RET:4.95E 13

成本时间:0.453676 RET:8.17441E 11

成本时间:0.203873 RET:8.17441E 11

为什么?

编译器通常尝试遵循IEEE754。在此标准中,划分是准确定义的。这意味着,对于每个a/b,都有一个脱颖而出的答案。如果将其修改为a*(1/b),结果可能会有所不同(您可能会看到此效果,如果您用16个重要数字打印双倍的双倍(

(

编译器通常可以选择放松。GCC具有-FFAST -MATH,VC具有/fp:fast。