以零执行时间循环


74

是否有可能执行时间为零的循环?我认为即使是一个空循环也应该有一个执行时间,因为存在与之相关的开销。


37
循环可能会被编译器展开和/或完全消除。
Elliott Frisch 2014年

4
优化编译器的主要工作之一是数据流分析。消除了产生不会流到任何地方的数据的计算,包括循环。确切的行为取决于您的编译器。
Dietrich Epp 2014年

6
基于问题过于广泛而得出结论是没有意义的,我们对此问题没有太多可能的答案,它完全适用于一般情况。
Shafik Yaghmour 2014年

3
这个问题都不适合太宽泛的标准。从经验中我们可以看到,答案并不太多,基本上只有一个精确答案,这两个答案只是在提供的细节上有所不同。答案不是太长,尽管可以扩展,但要想完美地解决目前存在的主题问题,就需要很长的路要走。
Shafik Yaghmour 2014年

2
@georg:但是流水线可以将某条指令的观察处理时间减半,因为它与同一条CPU周期中的另一条指令一起执行。如果“另一条指令”是您的NOP,则只需要原始指令周期即可。
Jongware

Answers:


121

是的,在假设规则下,编译器仅需模拟代码的可观察行为,因此,如果您的循环没有任何可观察的行为,则可以对其进行完全优化,因此有效执行时间为零。

例子

例如下面的代码:

int main()
{
  int j = 0 ;
  for( int i = 0; i < 10000; ++i )
  {
    ++j ;
  }
}

gcc 4.9使用-O3flag编译的结果基本上减少到以下内容(请参见live):

main:
  xorl  %eax, %eax  #
  ret

几乎所有允许的优化都属于“假设”规则,我知道的唯一例外是复制Elison,它可以实现可观察的行为。

其他一些示例包括消除无效代码,这些代码可以删除编译器可以证明永远不会执行的代码。例如,即使以下循环确实包含副作用,也可以对其进行优化,因为我们可以证明它永远不会被执行(实时查看):

#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 ) ;

可以优化为(观看直播):

movl    $10000, %esi    #,
movl    $.LC0, %edi #,
xorl    %eax, %eax  #
call    printf  #

我们可以看到不涉及循环。

该标准涵盖的规则在哪里

AS-如果规则被覆盖在C99标准草案,5.1.2.3 计划执行它说:

在抽象机中,所有表达式均按语义指定的方式求值。如果实际实现可以推断出未使用其值并且没有产生所需的副作用(包括由调用函数或访问易失性对象引起的副作用),则无需对表达式的一部分进行求值。

AS-如果规则也适用于C ++,gcc会产生在C ++中模式相同的结果为好。C ++标准草案在1.9 程序执行部分中对此进行了介绍:

本国际标准中的语义描述定义了参数化的不确定性抽象机器。本国际标准对一致性实现的结构没有要求。特别是,它们不需要复制或模拟抽象机的结构。相反,需要遵循实现以(仅)模拟抽象机的可观察行为,如下所述。5


我敢打赌,大多数(如果不是全部)语言规范都有一个“如果”规则。如果不使用并且没有副作用,通常没有必要进行计算。这样只会浪费时间和精力。
Craig S. Anderson

16
@CraigAnderson:大部分时间都是如此,但是在极少数情况下,您确实希望执行无用的计算,例如在加密操作中,您希望所有代码路径占用相同的时间以防止计时。频道攻击
亚当·罗森菲尔德

换句话说:对于执行实际的,不可避免的,不可模仿的工作的实循环,答案是:。对于仅做多余事情的伪循环:
Lutz Prechelt'2

52

是的-如果编译器确定循环为死代码(永远不会执行),则不会为其生成代码。该循环将有0个执行时间,尽管严格说来,它在机器代码级别上并不存在。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.