【问题标题】:Hints for the compiler to help it with the optimization task提示编译器帮助它完成优化任务
【发布时间】:2010-11-14 22:14:50
【问题描述】:

'Surviving the Release Version' 文章中的 const and volatile 章节让我想到编译器可以使用 const 关键字作为其优化工作的提示。

您知道编译器的其他一些优化提示或函数的设计原则,以便编译器可以将它们内联吗?

顺便问一下,你将原始类型函数参数声明为 const 还是 const 引用(如 void foo(const int i)void foo(const int& i))?

谢谢!

【问题讨论】:

    标签: c++ optimization compiler-construction compiler-optimization


    【解决方案1】:

    const 限定条件很少能帮助编译器优化您的代码。您可以在 Herb Sutter 的 "Constant Optimization?" 中阅读更多关于为什么会这样的信息

    关于你的最后一个问题:一般来说,你应该更喜欢通过值传递那些复制起来很便宜的东西(比如基本类型对象--ints 和floats 等等--以及小类类型对象)并通过 const 引用传递其他类型。这是一个非常普遍的规则,有很多注意事项和例外情况。

    【讨论】:

      【解决方案2】:

      一旦您启用一些优化,编译器就会注意到参数i 永远不会被修改,因此您将其声明为int 还是const int 对生成的代码无关紧要。

      const & 传递参数的目的是避免不必要的复制。在小参数(一个机器字或更少)的情况下,这不会带来更好的性能,所以你不应该这样做。 foo(int)foo(const int&) 效率更高。

      【讨论】:

        【解决方案3】:

        这两种形式都没有实际好处。如果类型小于单个机器字,则按值取值。另一件事是现代编译器的语义分析远远高于 const 可以和不能做的事情,如果它是预编译的或者你的代码非常复杂,你只能应用优化。您链接到的文章已有好几年的历史了,从那时起编译器除了大幅改进外什么也没做。

        【讨论】:

          【解决方案4】:

          我认为编译器不能使用 const 关键字进行优化,因为在任何时候都可以抛弃 const 。

          更多的是为了正确而不是优化。

          【讨论】:

          • 错误的假设。并非总是允许将const 抛开,即在const int i = 5 中,i 的常量可能不会被抛开。优化器可能(并且将会!)依赖于此,将5 替换为变量访问。当您尝试抛弃 const 对象的 const 特性时,您会得到未定义的行为,因此优化器可能会发出不适合这些情况的代码。
          • 我明白了。但是,这种情况下的 const 有什么不同吗?编译器不会知道“i”没有改变并内联吗?
          【解决方案5】:

          我想到了一些“通用编译器”。

          • const 暗示变量永远不会改变
          • volatile 暗示变量可以随时更改
          • 限制关键字
          • 内存屏障(向编译器提示特定的顺序)- 可能不是“优化”。
          • 内联关键字(使用非常谨慎)

          然而,所有这些都应该只来自广泛的分析例程,以便您了解实际需要优化的内容。一般来说,编译器非常擅长优化,而无需程序员提供太多提示。

          【讨论】:

          • 在那些对现代编译器进行优化的唯一方法中,restrict 关键字......它不是标准的 C++。
          【解决方案6】:

          如果您查看 Linux 内核或类似项目的源代码,您会发现所有传递给 gcc(或使用的任何编译器)的优化线索。 Linux 内核使用 gcc 提供的所有功能,即使它不在标准中。

          This page 总结了 gcc 对 C 语言的扩展。我在这里提到 C 是因为 C 中也使用了 const 和 volatile。不仅仅是 C 或 C++,编译器优化似乎是这里问题的焦点。

          【讨论】:

            【解决方案7】:

            我不认为const 的真正目的与优化有很大关系,尽管它有帮助。 编译时检查的真正价值不是防止你修改你不应该修改的东西,即防止错误吗?

            对于您不打算修改的小参数,请使用按值调用。

            对于您不打算修改的大参数,使用引用调用或传递地址(基本上是相同的),以及const

            对于您要修改的大小参数,请删除const

            顺便说一句:如果它是新闻,为了真正的性能,你需要知道如何通过分析来找到你实际遇到的问题。没有编译器可以为您做到这一点。

            【讨论】:

              猜你喜欢
              • 2012-11-04
              • 1970-01-01
              • 1970-01-01
              • 2020-06-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-07
              相关资源
              最近更新 更多