繁体   English   中英

时间与“好像”规则

[英]Timing vs the “as-if” rule

一般来说, 关于“as-if”规则有一个很好的问题,但我想知道在测量时间方面是否有任何例外。

考虑一下(取自此处略有修改):

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任何优化。 这里的重点是“as-if”规则并不直接适用于测量的时间。 当然,在应用优化时,测量的时间不应该是恒定的。

所以我的问题是:当根据“as-if”规则允许编译器将其重新排列为以下之一时,我怎么可能用上面的代码可靠地测量时间?

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;

甚至“更优化”:

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

我认为没有理智的编译器会这样做,但是究竟是什么阻止了编译器进行这种“优化”?

TL;博士...

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

编译器不会这样做,您可以确定这一点。

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

编译器不能围绕黑盒函数调用重新排序,因为它不能假设这不会有任何副作用或包含任何障碍。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM