C++ &引用;“神奇的”;英特尔c&x2B+;编译器:发生了什么事?

C++ &引用;“神奇的”;英特尔c&x2B+;编译器:发生了什么事?,c++,intel,icc,C++,Intel,Icc,我是尼克斯。在循环测试中,有简单的C++代码。 #include <iostream> #include <time.h> int main() { double sum = 0.0; int n ; std::cout << "n ?" << std::endl; std::cin >> n ; clock_t t_start = clock(); for (i

我是尼克斯。在<代码>循环测试中,有简单的C++代码。
#include <iostream>
#include <time.h>

int main()
{
      double sum = 0.0;
      int n ;
      std::cout << "n ?" << std::endl;
      std::cin >> n ;
      clock_t t_start = clock();
      for (int i = 0 ; i < n ; ++i)
      {
            sum+= static_cast<double>(i);
      }
      clock_t t_end = clock();
      clock_t diff = t_end - t_start;
      double diffd = static_cast<double>(diff)/CLOCKS_PER_SEC;
      std::cout << diffd << " seconds." << std::endl;
      sum*=1.0;
      return 0;
}
当我测试它时,我得到了以下奇怪的结果:

My-MacBook-Air:tmp11 XXXX$ ./looptest 
n ?
10000
4e-06 seconds.
My-MacBook-Air:tmp11 XXXX$ ./looptest 
n ?
100000
3e-06 seconds.
My-MacBook-Air:tmp11 XXXX$ ./looptest 
n ?
1000000
3e-06 seconds.
My-MacBook-Air:tmp11 XXXX$ ./looptest 
n ?
1000000000
2e-06 seconds.
My-MacBook-Air:tmp11 XXXX$ ./looptest 
n ?
4294967295
3e-06 seconds.

奇怪,不是吗?这里发生了什么事?当然,使用gnu-5.2的
g++
而不是
icpc
进行编译会产生预期的结果(n增加时时间会增加)。

sum
不会被读取,因此所有变量赋值都被删除。这使得for循环为空,因此它也被删除。因此,剩下的是:

#include <iostream>
#include <time.h>

int main()
{
      int n ;
      std::cout << "n ?" << std::endl;
      std::cin >> n ;
      clock_t t_start = clock();
      clock_t t_end = clock();
      clock_t diff = t_end - t_start;
      double diffd = static_cast<double>(diff)/CLOCKS_PER_SEC;
      std::cout << diffd << " seconds." << std::endl;
      return 0;
}
#包括
#包括
int main()
{
int n;
标准::cout n;
clock_t_start=clock();
clock_t_end=clock();
时钟差=t\U结束-t\U开始;
双diffd=每秒钟的静态(diff)/时钟;

STD::CC++编程中没有任何神奇的东西。跳过这个概念,严肃起来!他把“神奇”在引号中表示它不是真的神奇。尝试使用g++和-ffast math tooth优化器,优化器能够确定您没有对计算结果做任何事情,因此它可能只是删除了您的循环。@πάνταῥεῖ, 不过,未定义的行为可能会导致一些非常神奇的优化后行为。事实上,在后面添加一些涉及
sum
after的内容(比如对某个因子进行aksing运算并将sum乘以after)会产生一个O(n)对于初始代码,time.和
-O
,产生相同的结果。但有一个问题:
sum
确实不可读,但出现在两次之间,用于产生一个时间间隔,然后打印出来。为什么编译器没有检测到这一点?重新格式化:编译器有多聪明?;-)@user10000100_u u:现代优化编译器非常聪明。例如,请参阅。@user10000100_编译器聪明地尽可能快地生成正确的函数结果(或您告诉它做的任何其他优化),而不是检测您想要测量的副作用。尽管如此,您感兴趣的是测量
时钟
调用的开销。
#include <iostream>
#include <time.h>

int main()
{
      int n ;
      std::cout << "n ?" << std::endl;
      std::cin >> n ;
      clock_t t_start = clock();
      clock_t t_end = clock();
      clock_t diff = t_end - t_start;
      double diffd = static_cast<double>(diff)/CLOCKS_PER_SEC;
      std::cout << diffd << " seconds." << std::endl;
      return 0;
}