在这个网站上已经有很多性能问题了,但是在我看来,几乎所有的问题都是非常具体的,而且相当狭窄。几乎所有人都重复了避免过早优化的建议。
我们假设:
代码已经正常工作了
所选择的算法对于问题的环境已经是最优的
对代码进行了测量,并隔离了有问题的例程
所有优化的尝试也将被衡量,以确保它们不会使事情变得更糟
我在这里寻找的是策略和技巧,在一个关键算法中,当没有其他事情可做,但无论如何都要挤出最后百分之几。
理想情况下,尽量让答案与语言无关,并在适用的情况下指出所建议的策略的任何缺点。
我将添加一个带有我自己最初建议的回复,并期待Stack Overflow社区能想到的任何其他东西。
目前最重要的限制因素是有限的内存带宽。多核只会让情况变得更糟,因为带宽是在核之间共享的。此外,用于实现缓存的有限芯片区域也分配给了内核和线程,这进一步恶化了这个问题。最后,保持不同缓存一致性所需的芯片间信号也会随着核数的增加而增加。这也增加了一个惩罚。
这些是您需要管理的影响。有时是通过对代码的微观管理,但有时是通过仔细考虑和重构。
很多注释已经提到了缓存友好的代码。至少有两种不同的风格:
避免内存读取延迟。
降低内存总线压力(带宽)。
第一个问题与如何使数据访问模式更规则有关,从而使硬件预取器更有效地工作。避免动态内存分配,这会将数据对象分散在内存中。使用线性容器代替链表、散列和树。
第二个问题与提高数据重用有关。修改算法以处理适合可用缓存的数据子集,并在数据仍在缓存中时尽可能多地重用这些数据。
更紧密地封装数据并确保在热循环中使用缓存线路中的所有数据,将有助于避免这些其他影响,并允许在缓存中安装更多有用的数据。
不可能有这样的全面陈述,这取决于问题领域。一些可能性:
因为你没有直接指定你的应用程序是100%计算:
搜索阻塞的调用(数据库,网络硬盘,显示更新),并隔离它们和/或将它们放入线程中。
如果你使用的数据库恰好是Microsoft SQL Server:
研究nolock和rowlock指令。(在这个论坛上有一些讨论。)
如果你的应用是纯粹的计算,你可以看看我关于旋转大图像缓存优化的问题。速度的提高使我大吃一惊。
这是一个长期的尝试,但它可能提供了一个想法,特别是如果您的问题是在成像领域:代码中旋转位图
另一个是尽量避免动态内存分配。一次分配多个结构,一次释放它们。
否则,请确定最紧密的循环,并将它们与一些数据结构一起张贴在这里(无论是伪的还是非的)。