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