计时与"as-if"规则
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
的优化。这里的重点是"如果"规则不直接适用于测量时间。当然,在应用优化时,测得的时间不是应该恒定的。
所以我的问题是:根据"如果"规则,允许编译器将其重新排列为以下一个?
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; dr ...
- 人们可以观察优化和非优化代码之间的运行时差
- 如果允许编译器优化实施测量时间,那么什么阻止编译器根本不为时机创建任何代码?
为了应用AS-IF规则,编译器必须证明所提出的更改对可观察的行为没有影响。您是正确的,时间的流逝不是可观察到的行为。但是,在重新排序功能的情况下,必须证明调用该函数的顺序不会影响可观察的行为。
使用定时功能始终涉及一些用于测量时间的机制,这些机制将无法证明可以证明这是安全的。例如,它可能涉及无法检查的不透明系统API功能或驱动程序功能的调用。如果我们以最透明的示例,每次采用状态时,它只是按1个单位前进的单调软件时钟,则无法证明呼叫顺序并不重要,因为这确实很重要。
<</p>编译器不会做到这一点,您可以确定。
在纯理论中,将允许使用系统时间涉及系统呼叫,这是编译器的完整黑匣子。
编译器无法在黑匣子功能调用周围重新排序,因为它不能假设这不会有任何副作用或包含任何障碍。
相关文章:
- 此代码是否违反一个定义规则
- 我的简单if-else语句是如何无法访问的代码
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- 生成文件不对文件使用隐式规则
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 函数如何在不这样做的情况下在新线程上运行"as if"?
- Problems in using ?: as if statement in C++
- 计时与"as-if"规则
- as-if规则是否防止编译器对全局/成员变量的访问重新排序
- c++ as-if规则是否允许存储区重新排序
- 振奋精神,为什么需要as<>指令?(又名帮助我了解属性兼容性规则)
- C++11 条件包含控制表达"types act as if same representation as" ?
- [conv]/6 中"The expression e is used as a glvalue if and only if the initialization uses it as a glva