优化程序性能之优化编译器的能力与局限

本文探讨了优化程序性能的策略,包括选择合适的算法与数据结构,以及如何利用编译器进行优化。文章强调了避免内存别名和使用restrict关键字的重要性,讨论了内联函数对优化的影响,同时也指出编译器的优化局限性,如无法判断函数是否有副作用。最后,提出了编写无歧义代码以帮助编译器优化的建议。
摘要由CSDN通过智能技术生成

优化程序性能

本章主要探讨内容:使用几种不同的程序优化技术,让程序运行得更加高效,并且在可维护性与性能间达到平衡。

将从以下的几个方面对程序进行优化

  1. 选择合适的算法与数据结构
  2. 尽可能使用使编译器更容易产生高效代码的方式来进行程序编写

程序优化的第一步应当是消除多余的不必要的工作,包括函数调用、条件测试与内存引用等。这些优化不依赖于目标机器。
基于Intel和AMD处理器,本章提出了一种高级模型。还设计了一种图形数据流来对处理器的指令执行形象化,并利用其预测程序的性能。

利用处理器提供的指令级别并行能力同时执行多条指令,提高程序性能。
通过研究程序的汇编代码是理解编译器以及产生的代码如何运行的最有效的手段之一。

不管有什么样的策略,在落实的时候都需要不断地试错、不断地修改源码并分析其性能。

优化编译器的能力和局限

GCC向用户提供了一些对它们所使用的优化的控制。最简单的控制就是指定优化级别。具体内容在GCC手册中有详细的说明。
一般使用-O2级别的优化。

注意,编译器只对程序使用安全的优化
所谓安全的优化,是指优化的结果不会导致任何运行结果的不同或者内容上的歧义。

避免内存别名的出现以及使用restrict进行优化

一个典型的例子——内存别名使用

// code 1
*a += *b;
*a += *b;

// code 2
*a += 2 * *b;

上述代码中,code2更加高效。
code1需要6次内存读取,而code2只需要3次
但是,编译器不会把code1优化为code2的形式——若指针a、指针b指向同一片内存,则code1的结果将与code2产生差异。

这种两个指针可能指向同一个内存位置的情况称之为内存别名使用。编译器必须假设不同的指针可能会指向内存中的同一个位置。

例如以下代码:

x = 1000;
y = 3000;
*q = y;
*p = x;
t = *q;

编译器必须假设指针p、q指向了同一片内存。若p、q内存地址不同,则t的取值为1000,否则为3000。
这就是一个妨碍优化的因素。如果编译器不能确定两个指针是否指向同一个位置,就必须假设什么情况都有可能。

另一个内存对齐的例子是(参考资料

#include <stdio.h>

void fun_1(int *target, 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值