考虑下面的代码:
int i=0;//initialize here
for (i=0;i<10;i++) {
//... do something here
}
因为我将在for循环中初始化,所以在定义它时我们不需要初始化它。但是如果我们做了初始化,那么在翻译成二进制代码后会有任何开销吗?
答案 0 :(得分:3)
编译器不会动态分配自动变量。可以这么说,没有“初学者”。因此,除了防止范围问题之外,移动变量声明背后没有真正的目的。
答案 1 :(得分:2)
编译器通常能够简单地完成这样的简单案例。最好的方法是将int i = 0放在for循环中。如果你需要在循环之后使用i,那么先手动启动它并将for循环的init部分留空。
答案 2 :(得分:0)
验证您要生成汇编语言的开销。 你可以通过
来做到这一点gcc -c -O0 -S
您需要使用-c
标记,并且会生成名为yourcode.s
的文件。
在重新编写gcc命令之前重命名每个汇编语言.s文件,并使用每个编译器选项进行优化, -O1,-O2,-O3 。
然后,您可以从这些汇编语言文件中确定确切的开销,以及它是否有效。
int main ( int argc, char *argv[] )
{
int i;
int j;
i=5543644; /* to have or not to have this line*/
for ( i = 0; i < 2342465; i++ )
j = i;
return 0;
}
鉴于此代码示例,在针对i=5543644
存在且不存在的情况下使用优化 -O0 进行编译时,生成的两个汇编语言文件的唯一区别是一行是
movl $5543644, -8(%rbp)
将数据值 5543644 复制到 i 的内存地址中。我使用了零以外的值,使其在汇编语言中显而易见。
使用编译器优化 -O3 时,生成的两个汇编语言文件相同。这证明优化会导致编译器在i=5543644;
循环之前直接识别for
无用,并且在执行 -O0 时找到的结果movl
行是没有生成。
使用gcc 4.3.4测试。
从简单的int i = 0;
代码示例中,我不需要知道没有真正的开销,但是因为代码变得非常庞大和复杂,如果没有用i = 5543644;
直接在for循环之前,它可能不会被优化。必须仔细检查源代码和汇编语言才能做出决定。
如果确实发生了这种类型的数据分配,例如在嵌套for循环内以及OPENMP或其他并行化指令中导致它发生数百万或数十亿次,具体取决于代码,那么是的,这将导致开销。可能有多重要可能是非常主观的。