2013 年主题演讲:Chandler Carruth:优化 C++ 的新兴结构
- 42:45
您不需要输出参数,我们在 C++ 中有值语义。 ...每当你看到有人争论 nonono 我不会按值返回,因为复制成本太高,从事优化器工作的人就会说他们错了。好的?我还没有见过任何一段代码表明这个论点是正确的。 ...人们没有意识到值语义对优化器有多么重要,因为它完全澄清了别名场景。
任何人都可以将此放在这个答案的上下文中:https://stackoverflow.com/a/14229152
我听说不断重复,但是,对我来说,返回某些内容的函数是source。通过引用的输出参数从函数中获取该特征,并且从函数中删除这种硬编码特征允许人们在外部进行管理,即如何存储/重用输出。
我的问题是,即使在那个答案的背景下,有没有办法告诉,重组代码其他一些相等的方式,“现在看看,这种方式的值语义不会丢失输出参数版本”,或者 Chandler 评论特定于某些人为的情况?我什至看到安德烈·亚历山德雷斯库(Andrei Alexandrescu)在一次演讲中争论这个问题并告诉您无法逃避使用 by ref 输出以获得更好的性能。
对于安德烈评论的另一种看法,请参见Eric Niebler:输出参数、移动语义和状态算法.
这要么是夸大、概括、笑话,要么是 Chandler 的“完美合理性能”(使用现代 C++ 工具链/库)的想法对我的程序来说是不可接受的。
我发现它的优化范围相当狭窄。惩罚超出了这个范围,由于程序中的实际复杂性和设计,不能忽视这一点 - 堆分配就是一个例子getline
例子。尽管您尝试减少特定的优化,但它们可能始终适用于相关程序,也可能并不总是适用。现实世界的结构将引用可能存在别名的内存。您可以减少这种情况,但相信您可以消除混叠(从优化器的角度来看)是不切实际的。
当然,RBV 可能是一件很棒的事情 - 只是它并不适合所有情况。甚至您引用的链接也指出了如何避免大量分配/释放。真实的程序和其中的数据结构要复杂得多。
在演讲的后面,他继续批评成员函数的使用(参考:S::compute()
)。当然,有一点需要注意,但是完全避免使用这些语言功能真的合理吗,因为它使优化器的工作更容易?不会。它总是会产生更具可读性的程序吗?不会。这些代码转换是否总能带来明显更快的程序?不。转换代码库所需的更改值得您投入时间吗?有时。您能否吸取一些观点并做出更明智的决策,从而影响您现有或未来的某些代码库?是的。
有时,它有助于分解程序的执行方式,或者它在 C 中的样子。
优化器不会解决所有性能问题,并且您不应该假设您正在处理的程序是“完全脑死亡和损坏的设计”来重写程序,也不应该相信使用 RBV 总是会导致“完美合理的性能” ”。您可以利用新的语言功能并使优化器的工作变得更轻松,尽管可以获得很多好处,但通常还有更重要的优化需要投入时间。
考虑一下提议的改变是没问题的;理想情况下,在采用这些建议之前,您应该衡量此类更改对现实世界执行时间的影响以及对源代码的影响。
对于您的示例:即使按值复制+分配大型结构也会产生巨大的成本。除了运行构造函数和析构函数的成本(以及它们获取和拥有的资源的相关创建/清理,如您引用的链接中指出的)之外,即使像避免不必要的结构复制这样简单的事情也可以为您节省大量 CPU如果您使用参考文献,则需要时间(如果适用)。结构副本可能就像一个简单的memcpy
。这些不是人为的问题;而是人为的问题。它们出现在实际的程序中,并且复杂性会随着程序的复杂性而大大增加。减少某些内存的别名和其他优化是否值得付出成本,并且它是否会带来“完全合理的性能”?不总是。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)