应该给编译器留下哪些优化?

apa*_*ana 1 c optimization

假设您选择了最有效的算法来解决性能优先的问题,现在您正在实施它,您必须决定如下细节:

v[i*3+0]v[i*3+1]v[i*3+2]包含粒子速度的分量i,我们要计算总动能。假设所有粒子都具有相同的质量,人们可以写:

inline double sqr(double x)
{
    return x*x;
}

double get_kinetic_energy(double v[], int n)
{
    double sum = 0.0;

    for (int i=0; i < n; i++)
        sum += sqr(v[i*3+0]) + sqr(v[i*3+1]) + sqr(v[i*3+2]);

    return 0.5 * mass * sum;
}
Run Code Online (Sandbox Code Playgroud)

为了减少乘法次数,可以写成:

double get_kinetic_energy(double v[], int n)
{
    double sum = 0.0;

    for (int i=0; i < n; i++)
    {
        double *w = v + i*3;
        sum += sqr(w[0]) + sqr(w[1]) + sqr(w[2]);
    }

    return 0.5 * mass * sum;
}
Run Code Online (Sandbox Code Playgroud)

(人们可以编写一个乘法次数更少的函数,但这不是这个问题的重点)

现在我的问题是:既然许多C编译器可以自动进行这种优化,那么开发人员应该在哪里依赖编译器以及她/他应该在哪里尝试手动进行一些优化?

Lun*_*din 7

开发人员应该在哪里依赖编译器以及她/他应该在哪里尝试手动进行一些优化?

  1. 我对目标硬件以及 C 代码如何转换为汇编程序有相当深入的了解吗?如果不是,请忘记手动优化。

  2. 该代码中是否存在任何明显的瓶颈 - 我如何知道它首先需要优化?明显的罪魁祸首是 I/O、复杂循环、忙等待循环、幼稚算法等。

  3. 当我发现这个瓶颈时,我到底是如何对其进行基准测试的?我是否确定问题不在于基准测试方法本身?SO 的经验表明,十分之九的奇怪性能问题可以通过不正确的基准测试来解释。包括:禁用编译器优化的基准测试...

从那里开始,您可以开始查看特定于系统的事物以及算法本身 - 有太多的事情需要考虑,无法在 SO 答案中涵盖。针对低端微控制器和 64 位台式 PC(以及介于两者之间的所有设备)优化代码之间存在巨大差异。