时间与" as-if"规则

时间:2017-10-04 19:34:48

标签: c++ performance optimization time-measurement as-if

总的来说有一个很棒的question about the "as-if" rule,但我想知道在测量时间方面是否有任何重复。

考虑这一点(取自here稍加修改):

using std::chrono;
auto begin = steady_clock::now();

auto result = some_lengthy_calculation(some_params);

auto end= std::chrono::steady_clock::now();

std::cout << "Time diff = " << duration_cast<microseconds>(end - begin).count() <<std::endl;
std::cout << "Result = " << result;

允许编译器应用导致相同result的任何优化。这里的重点是&#34; as-if&#34;规则不适用于直接测量的时间。当然,在应用优化时,测量的时间不应该是恒定的。

所以我的问题是:根据&#34; as-if&#34;以及如何使用上述代码可以可靠地测量时间。规则,允许编译器将其重新排列为以下之一?

auto temp = some_lengthy_calculation(some_params); // clever "optimization", precompute some stuff

auto begin = steady_clock::now();
auto result = temp;               // yay, I can use it here to pretend to be faster
auto end = steady_clock::now();

std::cout << "Time diff = " << duration_cast<microseconds>(end - begin).count() <<std::endl;
std::cout << "Result = " << result;

甚至&#34;更优化&#34;:

std::cout << "Time diff = " << 42 <<std::endl;
std::cout << "Result = " << some_lengthy_calculation(some_params);

我认为没有理智的编译器会这样做,但究竟是什么阻止了编译器这样做&#34;优化&#34;?

TL; DR ...

  • 可以观察优化和非优化代码之间的运行时差异
  • 如果允许编译器优化影响测量时间,是什么阻止编译器根本不创建任何代码?

2 个答案:

答案 0 :(得分:2)

对于要应用的As-If规则,编译器必须证明建议的更改对可观察行为没有影响。你是正确的,时间的流逝不是一个可观察的行为。但是,在重新排序函数的情况下,它必须证明调用函数的顺序不会影响可观察的行为。

使用计时功能总是会涉及一些测量时间的机制,编译器无法证明这些机制可以安全地重新排序。例如,它可能涉及调用不能检查的不透明系统API函数或驱动程序函数。如果我们采用最透明的例子,一个单调的软件时钟,每次采取状态只需要前进1个单位时间,就无法证明呼叫顺序并不重要因为它确实很重要。

答案 1 :(得分:1)

编译器不会这样做,你可以确定。

虽然在纯粹的理论中,它是允许的,但系统时间涉及系统调用,这对于编译器来说是一个完整的黑盒子。

编译器无法对黑匣子函数调用进行重新排序,因为它不能认为这不会产生任何副作用或包含任何障碍。