我正在尝试测试一系列用于矩阵向量计算的库。为此,我只是做一个大循环而在里面我调用我想要的例程。非常简单。但是我有时会看到,当我增加编译器的优化级别时,无论循环有多大,时间都会降至零。请参阅下面的示例,我尝试计算C宏来计算跨产品。编译器在做什么?我怎样才能避免它,但允许对浮点算术进行最大程度的优化?提前谢谢
以下示例是在具有i5 intel处理器的计算机上使用g ++ 4.7.2编译的。 使用优化级别1(-O1)需要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;
}
答案 0 :(得分:2)
根据最终用户可见的内容,问问自己,您的计划实际上做了什么?
显示计算结果:get_time()-start
。循环的内容与该计算的结果无关,因为您实际上从未在循环中使用被修改的变量。
因此,编译器会优化整个循环,因为它是无关紧要的。
一种解决方案是输出循环中被修改的变量的最终状态,作为cout
语句的一部分,从而迫使编译器计算循环。但是,智能编译器也可以确定循环总是计算相同的东西,并且它可以简单地将结果直接插入到cout
语句中,因为不需要在运行时实际计算它。作为解决方法,您可以例如要求在运行时提供循环的其中一个输入(例如,从文件,命令行参数,cin
等读取)。
有关更多(可能更好)的解决方案,请查看此重复主题:Force compiler to not optimize side-effect-less statements