如果你有一个函数接受一个数组作为参数并用该数组调用另一个函数并用它调用另一个函数,那么堆栈将包含许多指向该数组的指针的副本。我只想到了一种缓解这个问题的有趣方法,但我想知道它是否值得实施。
有没有人知道堆栈在实践中包含重复指针的频率是多少?
修改
只是为了澄清,我没有优化给定的程序,而是考虑为my VM编写一种新的优化传递。我的benchmarks表明我当前的解决方案导致最多70%的总运行时间用于堆栈操作。我正在考虑的优化过程将在编译时生成代码 ,它将执行相同的操作,但指针(可能)会更少地在堆栈上重复。我对以前任何测量堆栈重复数量的研究感兴趣,因为这有助于我量化我的优化潜力。例如,如果知道实际程序在实践中没有将指针推到堆栈上那么我的优化就没用了。
此外,这些堆栈操作是由于我的VM生成的代码,确保垃圾收集器可以看到本地保存的指针,而不仅仅是因为两个回答者当前都假设的函数参数。它们实际上是阴影堆栈上的操作而不是主堆栈。
答案 0 :(得分:2)
首先,答案取决于您的申请。
其次,即使有很高的重复,我怀疑在实施你描述的机制方面有多大意义,甚至在一般情况下它是可能的。如果你调用一个方法并传递参数,你必须以这种或那种方式进行。
以某种特定的方式执行它可能是有利的 - 例如,有几个函数调用约定和许多C / C ++编译器(例如gcc)允许您在堆栈上传递参数或通过寄存器进行选择。在某些情况下,后者可能会更快 - 如果它可以帮助您的应用程序,您可以尝试进行基准测试。
但是在一般情况下,检测堆栈上的重复值并“重用”它们的成本可能远远超过堆栈较小的任何收益。推送和弹出值的代码非常简单(在优化的情况下只是一些CPU指令),用于查找和重用重复项的代码 - 几乎没有。您还必须以某种方式存储有关堆栈中已有哪些值以及如何找到它们的信息 - 一种非常重要的数据结构。除了一些非常奇怪的情况,我认为这不会比实际复制的数据本身小。
你可以做的,就是以某种函数调用被消除的方式重写你的算法。例如,如果函数的结果仅取决于输入参数,则可以以某种方式缓存或记忆结果,从而避免使用相同值重复调用。这确实可以带来一些收益,尽管它通常是内存与CPU时间的权衡。在内存和CPU时间方面都很有可能获得优势。此外,重写算法并不是“避免堆栈上的数据重复”。
无论如何,对于原始问题,我认为这个想法不可行,你应该考虑其他地方的优化。
PS:你的用例可能有点类似于尾部调用优化,所以也许这是一个值得关注的方向 - 但如果你自己实现它,我也会认为这属于“改变你的算法”类别。也许从递归算法变为迭代算法也可能有所帮助。答案 1 :(得分:-1)
我可以建议接触实际的性能调整吗? (Here's my canonical example.)
在程序启动时间和结束时间之间,它使用的周期显然使用了100%的周期。 如果它进出函数,并将指针传递给数组,但什么都不做,那么毫不奇怪,大部分时间进入函数进入和退出,并传递参数。
如果编写程序P来执行任务T,则还有许多其他程序P'也可以执行任务T.其中一些程序比其他程序占用更少的周期,这些是最佳的。 最优的那些与非最优的方式不同的是,非最优的方式做的事情可以在没有的情况下完成。
因此,要优化任何程序,找出不必要的循环,并摆脱这些活动。该链接非常详细地显示了我是如何做到的。
尝试将更少的参数传递给函数可能需要也可能不需要,具体取决于您的诊断告诉您的内容。