Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ for循环条件中常数的计算 for(int i=0;i_C++_Loops_Optimization_As If - Fatal编程技术网

C++ for循环条件中常数的计算 for(int i=0;i

C++ for循环条件中常数的计算 for(int i=0;i,c++,loops,optimization,as-if,C++,Loops,Optimization,As If,在本例中,my_函数(my_常数)是在每次迭代时计算,还是自动存储?这是否取决于使用的优化标志?每次迭代都将对其进行评估。您可以通过执行以下操作来节省额外的计算时间 for(int i = 0; i < my_function(MY_CONSTANT); ++i){ //code using i } const int stop=my_函数(my_常数); 对于(int i=0;i程序执行来看到,它表示: […]相反,一致性实现需要仿真(仅) 抽象机器的可观察行为,如下所述 因此

在本例中,
my_函数(my_常数)
是在每次迭代时计算,还是自动存储?这是否取决于使用的优化标志?

每次迭代都将对其进行评估。您可以通过执行以下操作来节省额外的计算时间

for(int i = 0; i < my_function(MY_CONSTANT); ++i){
    //code using i
}
const int stop=my_函数(my_常数);
对于(int i=0;i
它必须像每次调用函数一样工作

但是,如果编译器可以证明每次函数结果都是相同的,那么它可以根据“as-if”规则进行优化

例如,对于标准容器,这通常发生在调用
.end()


一般建议:当对是否微优化一段代码有疑问时

  • 不要这样做
  • 如果您仍在考虑这样做,测量
  • 还有第三点,但我忘了,也许是,等等

  • 换句话说,决定是否使用变量是基于代码的清晰程度,而不是基于想象的性能。

    如果
    my_function
    声明为constexpr,并且参数实际上是常量,则在编译时计算该值,从而满足“仿佛”和“无数据竞争的顺序一致性”规则

    如果您的函数有副作用,它将阻止编译器将其移出
    for循环
    ,因为它不会满足“仿佛”规则,除非编译器可以推理将其移出

    编译器可能会内联
    my_函数
    ,将其作为循环的一部分进行缩减,并通过常量缩减发现它实际上只是一个常量,事实上删除调用并用常量替换它

    constexpr my_function(const int c);
    

    所以你问题的答案是。。。也许吧

    as-if规则下的现代优化编译器可能能够在您的。<代码>仿佛规则表示一致编译器只有仿真可观察的行为,我们可以通过草稿C++标准章节<代码> 1.9代码>程序执行来看到,它表示:

    […]相反,一致性实现需要仿真(仅) 抽象机器的可观察行为,如下所述

    因此,如果您使用的是常量表达式,并且
    my_函数
    没有明显的副作用,则可以对其进行优化。我们可以组合一个简单的测试():

    即使在
    不带常数的情况下
    也会内联计算,而不是执行函数调用:

    cmpl    $30, %ebx   #, i
    

    将在每次迭代时进行评估。最好将其存储为变量。@guygree可能重复,而不是重复,没有函数调用。@Basilevs,我不认为这会改变这里的情况,每次都需要重新计算表达式(无论该表达式是什么)。特别是我的回答很好地概括了这一点,我认为,原来的问题是完全不同的。谢谢你的额外建议。当我写我的问题时,我想到
    我的_常量
    是由一条“#define”指令预定义的,阅读上面与我自己相关的问题时,似乎最近的编译器会存储它。非常感谢!甚至不需要对周围的范围进行修改:
    for(int i=0,stop=my_函数(my_常量);i
    。最近,我的大部分
    for
    循环都是这样的。
    int my_function(const int c) {
        return 17+c; // inline and constant reduced to the value.
    }
    
    #include <stdio.h>
    
    #define blah 10
    
    int func( int x )
    {
      return x + 20 ;
    }
    
    void withConstant( int y )
    {
      for(int i = 0; i < func(blah); i++)
      {
        printf("%d ", i ) ;
      }
    }
    
    void withoutConstant(int y)
    {
      for(int i = 0; i < func(i+y); i++)
      {
        printf("%d ", i ) ;
      }
    }
    
    cmpl    $30, %ebx   #, i
    
    leal    0(%rbp,%rbx), %eax  #, D.2605