首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >哪些优化应该留给编译器?

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

Stack Overflow用户
提问于 2022-02-16 15:21:34
回答 4查看 102关注 0票数 1

假设您已经选择了最有效的算法来解决性能是第一优先的问题,而现在您正在实现它,那么您必须决定如下所示的细节:

v[i*3+0]v[i*3+1]v[i*3+2]包含了粒子i的速度分量,我们要计算出总动能。考虑到所有粒子的质量都一样,人们可以写:

代码语言:javascript
运行
复制
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;
}

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

代码语言:javascript
运行
复制
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;
}

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

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-02-16 20:27:18

看看gccclang如何处理您的代码,您所考虑的微观优化是徒劳的。编译器已经应用了标准的通用子表达式消除技术,这些技术移除了您想要消除的开销。

实际上,生成的代码一次使用XMM寄存器处理两个组件。

如果性能是必需的,那么下面是可以节省时间的步骤:

  • ,真正的法官是挂钟。编写一个包含真实数据的基准测试,并测量性能,直到得到一致的结果。

如果您有分析器,请使用

  • 来确定瓶颈(如果有的话)在哪里。改变那些看起来性能很好的部件的算法是一种有效的方法。

  • 试着从编译器那里获得最好的结果:研究优化选项,如果它们适合目标系统,就让编译器使用更激进的技术。例如,-mavx512f -mavx512cd允许gcc使用512位ZMM寄存器生成每次处理8个组件的代码。

这是一种非侵入性的技术,因为代码不会改变,所以您不会冒险通过手工优化代码来引入新的bug。

优化是一门困难的艺术。在我的经验中,简化代码可以获得更好的结果和更少的bug,而不是以牺牲可读性和正确性为代价添加额外的微妙内容来提高性能。

看一看代码,一个明显的简化似乎会产生相同的结果,并可能为优化器的工作提供便利(但同样,让墙上的时钟来判断):

代码语言:javascript
运行
复制
double get_kinetic_energy(const double v[], int n, double mass)
{
    double sum = 0.0;

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

    return 0.5 * mass * sum;
}
票数 2
EN

Stack Overflow用户

发布于 2022-02-16 16:13:11

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

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

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

当我发现这个瓶颈时,

  1. 如何准确地对其进行基准测试,并且我是否确定问题不在于基准测试方法本身?经验表明,在10个奇怪的性能问题中,大约有9个可以用不正确的基准来解释。包括:禁用编译器优化的基准测试.

从那时起,你就可以开始研究系统特定的东西,以及算法本身--有太多的事情要看,无法用这样的答案来回答。优化低端微控制器的代码和64位的桌面PC (以及两者之间的一切)是一个巨大的区别。

票数 5
EN

Stack Overflow用户

发布于 2022-02-16 15:43:05

有一件事看上去有点像过早的优化,但可能只是对语言能力的无知,那就是您拥有描述粒子的所有信息,这些信息被压缩成一个double值数组。

相反,我建议您分解这一点,通过创建一个结构来保存每个粒子上的三个数据点,从而使您的代码更容易阅读。此时,您可以创建一个或多个粒子的函数,并对它们进行计算。

这将比将粒子参数数的三倍传递给函数或尝试“分割”数组要容易得多。如果对您来说更容易推理,那么生成警告/错误的可能性就会降低。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71144522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档