在这个网站上已经有很多性能问题了,但是在我看来,几乎所有的问题都是非常具体的,而且相当狭窄。几乎所有人都重复了避免过早优化的建议。

我们假设:

代码已经正常工作了 所选择的算法对于问题的环境已经是最优的 对代码进行了测量,并隔离了有问题的例程 所有优化的尝试也将被衡量,以确保它们不会使事情变得更糟

我在这里寻找的是策略和技巧,在一个关键算法中,当没有其他事情可做,但无论如何都要挤出最后百分之几。

理想情况下,尽量让答案与语言无关,并在适用的情况下指出所建议的策略的任何缺点。

我将添加一个带有我自己最初建议的回复,并期待Stack Overflow社区能想到的任何其他东西。


当前回答

你在什么硬件上运行?您是否可以使用特定于平台化的优化(如向量化)? 你能找到更好的编译器吗?比如从GCC换成Intel? 你能让你的算法并行运行吗? 可以通过重新组织数据来减少缓存丢失吗? 可以禁用断言吗? 对编译器和平台进行微优化。在if/else语句中,把最常见的语句放在前面

其他回答

内联例程(消除调用/返回和参数推送) 试着用表查找(如果它们更快的话)消除测试/开关 展开循环(Duff的设备)到刚好适合CPU缓存的位置 本地化内存访问,以免耗尽缓存 如果优化器还没有本地化相关的计算 如果优化器还没有这样做,就消除循环不变量

目前最重要的限制因素是有限的内存带宽。多核只会让情况变得更糟,因为带宽是在核之间共享的。此外,用于实现缓存的有限芯片区域也分配给了内核和线程,这进一步恶化了这个问题。最后,保持不同缓存一致性所需的芯片间信号也会随着核数的增加而增加。这也增加了一个惩罚。

这些是您需要管理的影响。有时是通过对代码的微观管理,但有时是通过仔细考虑和重构。

很多注释已经提到了缓存友好的代码。至少有两种不同的风格:

避免内存读取延迟。 降低内存总线压力(带宽)。

第一个问题与如何使数据访问模式更规则有关,从而使硬件预取器更有效地工作。避免动态内存分配,这会将数据对象分散在内存中。使用线性容器代替链表、散列和树。

第二个问题与提高数据重用有关。修改算法以处理适合可用缓存的数据子集,并在数据仍在缓存中时尽可能多地重用这些数据。

更紧密地封装数据并确保在热循环中使用缓存线路中的所有数据,将有助于避免这些其他影响,并允许在缓存中安装更多有用的数据。

When you get to the point that you're using efficient algorithms its a question of what you need more speed or memory. Use caching to "pay" in memory for more speed or use calculations to reduce the memory footprint. If possible (and more cost effective) throw hardware at the problem - faster CPU, more memory or HD could solve the problem faster then trying to code it. Use parallelization if possible - run part of the code on multiple threads. Use the right tool for the job. some programing languages create more efficient code, using managed code (i.e. Java/.NET) speed up development but native programing languages creates faster running code. Micro optimize. Only were applicable you can use optimized assembly to speed small pieces of code, using SSE/vector optimizations in the right places can greatly increase performance.

在带有模板的语言(c++ /D)中,您可以尝试通过模板参数传播常量值。你甚至可以用开关来处理小的非常值集合。

Foo(i, j); // i always in 0-4.

就变成了

switch(i)
{
    case 0: Foo<0>(j); break;
    case 1: Foo<1>(j); break;
    case 2: Foo<2>(j); break;
    case 3: Foo<3>(j); break;
    case 4: Foo<4>(j); break;
}

缺点是缓存压力,因此这只会在深度或长期运行的调用树中获得,其中值在持续时间内是恒定的。

你在什么硬件上运行?您是否可以使用特定于平台化的优化(如向量化)? 你能找到更好的编译器吗?比如从GCC换成Intel? 你能让你的算法并行运行吗? 可以通过重新组织数据来减少缓存丢失吗? 可以禁用断言吗? 对编译器和平台进行微优化。在if/else语句中,把最常见的语句放在前面