用于计时测试的大循环在某种程度上被优化为零

large loop for timing tests gets somehow optimized to nothing?

本文关键字:优化 在某种程度上 大循环 测试 用于      更新时间:2023-10-16

我正在尝试测试矩阵向量计算的一系列库。为此,我只是做了一个大循环,在里面我调用我想要计时的例程。非常简单。然而,我有时会看到,当我增加编译器的优化级别时,无论循环有多大,时间都会降至零。请参阅下面的示例,其中我尝试计时C宏来计算叉乘。编译器在做什么?我怎么能避免它,但允许浮点运算的最大优化?提前谢谢你

下面的示例是在一台i5 intel处理器的计算机上使用g++ 4.7.2编译的。如果使用优化级别1(- 01),则需要0.35秒。对于二级或更高级别,它将下降到零。记住,我想要计算时间,所以我想要计算实际发生,即使,对于这个简单的测试,没有必要。

#include<iostream>
using namespace std;
typedef double  Vector[3];
#define VecCross(A,assign_op,B,dummy_op,C)              
(   A[0] assign_op (B[1] * C[2]) - (B[2] * C[1]),       
    A[1] assign_op (B[2] * C[0]) - (B[0] * C[2]),       
    A[2] assign_op (B[0] * C[1]) - (B[1] * C[0])        
)
double get_time(){
  return clock()/(double)CLOCKS_PER_SEC;
}
int main()
{
  unsigned long n = 1000000000u;
  double start;
  {//C macro cross product                                                                                                                                              
    Vector u = {1,0,0};
    Vector v = {1,1,0};
    Vector w = {1.2,1.2,1.2};
    start = get_time();
    for(unsigned long i=0;i<n;i++){
      VecCross (w, =, u, X, v);
    }
    cout << "C macro cross product: " << get_time()-start << endl;
  }
  return 0;
}

问问你自己,你的程序实际上做了什么,就终端用户可见的内容而言?

显示计算结果:get_time()-start。循环的内容与计算的结果没有任何关系,因为您从未实际使用在循环中修改的变量。

因此,编译器优化出整个循环,因为它是不相关的。

一种解决方案是输出在循环中被修改的变量的最终状态,作为cout语句的一部分,从而强制编译器计算循环。然而,一个聪明的编译器也可以找出循环总是计算相同的东西,它可以简单地将结果直接插入到您的cout语句中,因为没有必要在运行时实际计算它。作为解决这个问题的方法,例如,您可以要求在运行时提供循环的其中一个输入(例如,从文件、命令行参数、cin等中读取它)。

要了解更多(可能更好)的解决方案,请查看下面的重复线程:强制编译器不优化没有副作用的语句