是否可以有一个零执行时间的循环?我认为即使是一个空循环也应该有一个执行时间,因为它有与之相关的开销。
答案 0 :(得分:121)
是的,在 as-if规则下,编译器只能模拟代码的可观察行为,因此如果你有一个没有任何可观察行为的循环,那么它可以被优化完全离开,因此实际上没有执行时间。
实施例
例如以下代码:
int main()
{
int j = 0 ;
for( int i = 0; i < 10000; ++i )
{
++j ;
}
}
使用gcc 4.9
标记使用-O3
编译的基本上会缩减为以下内容( see it live ):
main:
xorl %eax, %eax #
ret
几乎所有的优化都属于 as-if规则,我所知道的唯一例外是copy elison,它可以影响可观察的行为。
其他一些示例包括dead code elimination,它可以删除编译器可以证明永远不会执行的代码。例如,即使以下循环确实包含副作用,它也可以进行优化,因为我们可以证明它永远不会被执行( see it live ):
#include <stdio.h>
int main()
{
int j = 0 ;
if( false ) // The loop will never execute
{
for( int i = 0; i < 10000; ++i )
{
printf( "%d\n", j ) ;
++j ;
}
}
}
循环将与前一个示例相同。一个更有趣的例子是循环中的计算可以推导成常量,从而避免需要循环(不确定这个属于的优化类别),例如:
int j = 0 ;
for( int i = 0; i < 10000; ++i )
{
++j ;
}
printf( "%d\n", j ) ;
可以优化到( see it live ):
movl $10000, %esi #,
movl $.LC0, %edi #,
xorl %eax, %eax #
call printf #
我们可以看到没有涉及循环。
标准
中涵盖的as-if规则在哪里草案C99标准部分5.1.2.3
程序执行中包含 as-if规则,其中包含:
在抽象机器中,所有表达式都按照指定的方式进行评估 语义学。实际的实现不需要评估部分内容 表达式,如果它可以推断出它的值没有被使用而且没有 产生所需的副作用(包括通过调用a引起的任何副作用) 功能或访问易失性对象。)
as-if rule也适用于C ++,gcc
也会在C ++模式下产生相同的结果。 C ++草案标准在1.9
程序执行:
本国际标准中的语义描述定义了一个 参数化非确定性抽象机。这个国际 标准对符合结构没有要求 实现。特别是,他们不需要复制或模仿 抽象机器的结构。相反,符合实施 需要模仿(仅)抽象的可观察行为 机器如下所述.5
答案 1 :(得分:52)
是 - 如果编译器确定循环是死代码(永远不会执行),那么它将不会为它生成代码。该循环将有0个执行时间,但严格来说它并不存在于机器代码级别。
答案 2 :(得分:12)
除了编译器优化之外,一些CPU架构(尤其是DSP)具有零开销循环,其中具有固定迭代次数的循环被硬件有效地优化,参见例如。 http://www.dsprelated.com/showmessage/20681/1.php
答案 3 :(得分:3)
编译器没有义务评估没有副作用且其结果被丢弃的表达式或表达式的一部分。
Harbison和Steele,C: A Reference Manual