除了其他人所说的,这里有一些速度优化的技术:
轮廓
找出代码中大部分时间都花在了哪里。只有优化该区域才能获得最大的利益。
展开循环
处理器不喜欢执行路径中的分支、跳转或更改。通常,处理器必须重新加载指令流水线,这会占用可用于计算的时间。这包括函数调用。
该技术是在循环中放置更多“组”操作并减少迭代次数。
将变量声明为寄存器
经常使用的变量应该声明为register
. 尽管 SO 的许多成员都表示编译器忽略了这个建议,但我发现并非如此。最坏的情况,你浪费了一些时间打字。
保持密集计算简短而简单
许多处理器在其指令流水线中有足够的空间来容纳小循环for
。这减少了重新加载指令流水线所花费的时间。
将您的大计算循环分配到许多小循环中。
在数组和矩阵的小部分上执行工作
许多处理器都有一个数据缓存,它是非常接近处理器的超高速内存。处理器喜欢从处理器外的内存中加载一次数据缓存。更多的负载需要时间来进行计算。在网上搜索“面向数据的设计缓存”。
考虑并行处理器术语
更改您的计算设计,以便它们可以轻松适应多个处理器。许多 CPU 具有多个可以并行执行指令的内核。一些处理器有足够的智能来自动将指令委托给它们的多个内核。
一些编译器可以优化代码以进行并行处理(查找编译器的编译器选项)。为并行处理设计代码将使编译器更容易进行这种优化。
分析函数的汇编列表
打印出你的函数的汇编语言列表。更改函数的设计以匹配汇编语言的设计或帮助编译器生成更优化的汇编语言。
如果您确实需要更高的效率,请优化汇编语言并将其作为内联汇编代码或作为单独的模块放入。我一般更喜欢后者。
例子
在您的情况下,取泰勒展开式的前 10 个项,分别计算它们并放入单个变量中:
double term1, term2, term3, term4;
double n, n1, n2, n3, n4;
n = 1.0;
for (i = 0; i < 100; ++i)
{
n1 = n + 2;
n2 = n + 4;
n3 = n + 6;
n4 = n + 8;
term1 = 4.0/n;
term2 = 4.0/n1;
term3 = 4.0/n2;
term4 = 4.0/n3;
然后总结你的所有条款:
result = term1 - term2 + term3 - term4;
// Or try sorting by operation, if possible:
// result = term1 + term3;
// result -= term2 + term4;
n = n4 + 2;
}