为什么编译器似乎对不执行任何操作且不消除它们的循环很礼貌?
C 标准是否要求循环需要一些时间?
例如,以下代码:
void foo(void) {
while(1) {
for(int k = 0; k < 1000000000; ++k);
printf("Foo\n");
}
}
运行速度比这个慢:
void foo(void) {
while(1) {
for(int k = 0; k < 1000; ++k);
printf("Foo\n");
}
}
即使-O3
优化级别。
我希望删除允许的空循环,从而在两个代码上获得相同的速度。
“花费的时间”是编译器应该保留的副作用吗?
不,花费的时间不算作受假设规则保护的可观察行为:
[C++14: 1.8/5]:
执行格式良好的程序的一致实现应产生与具有相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为。然而,如果任何此类执行包含未定义的操作,则本国际标准对使用该输入执行该程序的实现没有任何要求(甚至不涉及第一个未定义操作之前的操作)。
[C++14: 1.5/8]:
一致实施的最低要求是:
- 对易失性对象的访问严格按照抽象机的规则进行评估。
- 在程序终止时,写入文件的所有数据应与根据抽象语义执行程序可能产生的可能结果之一相同。
- 交互设备的输入和输出动态应以这样的方式发生:在程序等待输入之前提示输出实际上被传递。交互设备的构成是由实现定义的。
这些统称为可观察的行为的程序。 [ Note:每个实现可以定义抽象语义和实际语义之间更严格的对应关系。——尾注]
这些循环可以合法地优化,事实上,在某些情况下,该标准使商榷尝试让这样做变得更加容易:
[C++14: 1.10/24]:
该实现可能假设任何线程最终都会执行以下操作之一:
- 终止,
- 调用库 I/O 函数,
- 访问或修改易失性对象,或者
- 执行同步操作或原子操作。
[ Note:这是为了允许编译器进行转换,例如删除空循环,即使无法证明终止也是如此。——尾注]
事实上,您的编译器可能会“礼貌”地注意到循环的意图these程序似乎正在减慢重复文本输出的发出。 :)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)