声明var外部循环不好?

时间:2016-08-08 11:03:06

标签: c++ performance loops memory declaration

我为我制作的DSP /音频应用程序编写了这个基本代码:

double input = 0.0;
for (int i = 0; i < nChannels; i++) {
      input = inputs[i];

并且一些DSP工程专家告诉我: &#34;你不应该在循环之外声明它,否则它会创建一个依赖项,编译器不能像它一样有效地处理它可能&#34;

我认为他正在谈论var input。为什么这个?是不是一次更好的去除并覆盖它?

也许有些事情与使用不同的内存位置有关?即注册而不是堆栈?

3 个答案:

答案 0 :(得分:7)

80年代早期的旧K&amp; R C编译器过去常常编写程序员编写的代码,程序员过去常常尽力生成优化的源代码。现代优化编译器可以返工,只要生成的代码与原始代码具有相同的可观察效果 。因此,假设input变量未在循环外使用,优化编译器可以优化行double input = 0.0;,因为在下一次分配之前没有可观察到的影响:input = inputs[i];。并且它可能与循环外的变量赋值相同(无论是在源C ++文件中它是否在内部)也是出于同样的原因。

简短的故事,除非你想为一个具有一个特定参数集的特定编译器生成代码,在这种情况下你应该彻底检查生成的汇编代码,你永远不应该担心那些低级优化。有人说编译器比你更聪明,其他人说编译器会以我编写的方式生成自己的代码

重要的是可读性和可变范围。这里input是循环的本地函数,因此它应该在循环内声明。完全停止。任何其他优化考虑都是无用的,除非您对低级优化有特殊要求(分析显示这些行需要特殊处理)。

答案 1 :(得分:3)

最好在循环中声明变量,但原因是错误的。

有一条经验法则:在尽可能小的范围内声明变量。您的代码更具可读性且不易出错。

至于性能问题,对于任何正确声明变量的现代编译器来说,它都没有关系。例如,clang完全取消了-O1变量与其自己的IR:https://godbolt.org/g/yjs4dA

然而,如果您使用地址input,变量can't be eliminated(轻松),并且您应该在循环中声明它,如果您关心性能。

答案 2 :(得分:3)

许多人认为声明变量会为您分配一些内存供您使用。它不像那样工作。它也没有分配寄存器。

它只会为您创建一个名称(和关联类型),您可以使用该名称将值的使用者与其生产者联系起来。

在一个50岁的编译器(或学生在他们的第三年编译器构建课程中编写的编译器)中,可以通过为堆栈上的变量分配一些内存来实现,并且每次引用变量时都使用它。它很简单,有效,而且效率极低。一个好的进步就是在可能的情况下将局部变量放在寄存器中,但是使用寄存器的效率低,并且它不是我们目前所处的位置(已经有一段时间了)。

将消费者与生产者联系起来可创建数据流图。在大多数现代编译器中,它是接收寄存器的图中的边缘。在您声明它们时,这将从任何变量中完全删除。它们不再存在。如果你在clang中使用-emit-llvm,你可以看到这个。

因此变量不是真实的,它们只是标签。根据需要使用它们。