《深入理解计算机系统》 优化程序性能的几个方法

本文几个优化程序性能的方法出自CSAPP第五章,通过不断修改源代码,试图欺骗编译器产生有效的代码

我们先引入度量标准每元素的周期数(CPE),表示程序性能。

我们先定义一个数据结构   data_t 代表数据类型

1 typedef struct{
2   long len;
3   data_t *data;
4 }vec_rec,*vec_prt;

以及常数IDENT和OP以便在后续的代码中进行不同的操作

//对所有向量的元素求和
#define IDENT 0
#define OP +

//对所有向量元素乘积
#define IDENT 1
#define OP *

我们首先看最初的代码版本,这是一个具有很大优化空间的代码,具体函数实现可参考原书。

 1 void combine1(vec_ptr v, data_t *dest)
 2 {
 3     long int i;
 4     *dest = IDENT;
 5     for (i = 0; i < vec_length(v); i++) {  //vec_length返回向量长度
 6         data_t val;
 7         get_vec_element(v, i, &val);//先进行边界检查再获取索引 i 处的值并赋值给val
 8         *dest = *dest OP val;
 9     }
10 }

1.消除循环的低效率

因为每次迭代循环的时候都必须对测试条件求值,但在此循环中,向量的长度值并不会随着循环的进行而改变,因此只需要计算一次vec_length(v)并保存在一个变量中,在后续的循环中使用此变量。

因此我们得到第二个版本的代码。这一常见的优化方式称为 代码移动,即识别要执行多次但值不会改变的代码,将其移动到代码前部分,避免重复求值。

 1 void combine2(vec_ptr v, data_t *dest)
 2 {
 3     long int i;
 4     long int length = vec_length(v);//只进行一次计算
 5     *dest = IDENT;
 6     for (i = 0; i < length; i++) {
 7         data_t val;
 8         get_vec_element(v, i, &val);
 9         *dest = *dest OP val;
10     }
11 }

2.减少过程调用

过程调用(函数调用)会带来开销,因此我们增加一个函数 get_vec_start.

1 data_t *get_vec_start(vec_ptr v)
2 {
3   return v->data;
4 }

由此我们可得第三版代码

void combine3(vec_ptr v,data_t *dest)
{
  long i;
  long length = vec_length(v);
  data_t *data = get_vec_start(v); 

  *dest = IDENT;
  for(i = 0;i<length;i++){
      *dest = *dest OP data[i];  //在循环中减少过程调用
  }
}

3.消除不必要的内存引用

虽然我们在第三版的代码中减少了过程的调用,但是第三版的代码相比第二版代码性能并没有明显的提升,这说明第三版中的代码还有别的制约性能的因素。

先看第三版代码的内循环汇编代码:

//dest in %rbx, data+i in %rdx, data+length in %rax

.L17
    vmovsd (%rbx),%xmm0
    vmulsd (%rdx),%xmm0,%xmm0
    vmovsd %xmm0,(%rbx)
    addq $8,%rbx
    cmpq %rax,%rdx
    jne    .L17

由汇编代码可见,第三版的代码对内存进行了两次读操作,一次写操作,通过引入一个临时变量,使其在循环中累计值,在循环结束后再讲值写入内存。

这样我们将循环中的内存操作又两次读一次写减少到一次读操作。程序性能显著提高。

void combine4(vec_ptr v, data_t *dest)
{
    long int i;
    long int length = vec_length(v);
    data_t *data = get_vec_start(v);
    data_t acc = IDENT;
    for (i = 0; i < length; i++) {
        acc = acc OP data[i];
    }
    *dest = acc;
}

原文地址:https://www.cnblogs.com/blzm742624643/p/9687690.html

时间: 2024-09-28 21:15:23

《深入理解计算机系统》 优化程序性能的几个方法的相关文章

深入理解计算机系统(5.1)------优化程序性能

你能获得的对程序最大的加速比就是当你第一次让它工作起来的时候. 在讲解如何优化程序性能之前,我们首先要明确写程序最主要的目标就是使它在所有可能的情况下都能正常工作,一个运行的很快的程序但是却是错误的结果是没有任何用处的,所以我们在进行程序性能优化之前,首先要保证程序能正常运行,且结果是我们需要的. 而且在很多情况下,让程序跑的更快是我们必须要解决的问题.比如一个程序要实时处理视频帧或者网络包,那么一个运行的很慢的程序就不能解决此问题.再比如一个计算任务计算量非常大,需要数日或者数周,如果我们哪怕

浅谈优化程序性能(下)

前言 在上一篇随笔中,我们谈到最小化一个计算中的操作数量不一定会提高它的性能.现在,就让我们来解开为什么会出现这种情况的原因吧. 处理器体系结构 在计算机的处理器中,处理一条指令包括很多操作,可以分为取指(fetch).译码(decode).执行(execute).访存(memory).写回(write back)和更新程序计数器(PC update)等几个阶段.这些阶段可以在流水线上同时进行,如下图所示: 上图中,F.D.E.M 和 W 分别代表上述五个阶段.当然,现代的处理器比这个示例要复杂

优化程序性能(CSAPP:5)

[前言]虽然现在没有接触过大型项目,但是工作了会注重性能.学习一下,应该能更好更快的理解别人写的经典优秀的代码.结合CSAPP和自己的理解,总结一下. 一.程序优化综述 1.高效程序的特点 (1)适当的算法和数据结构.方法和数据的组织形式无疑是最关键的,是优化的基础: (2)代码能够被编译器转化成高效的可执行代码.需要深入了解使用的编译器的优化方法,和常见的优化策略: (3)运用现代并行编程技术.多核以及硬件支持提供更大的加速可能,例如GPU: 2.优化程序的一般步骤 (1)消除不必要的工作,例

细数改善WPF应用程序性能的10大方法

WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势. 程序性能改善不是一蹴而就的,好的设计可以消除影响性能的问题,例如,在运行时构造对象就会对程序的性能造成影响.虽然WPF通过增强的导航等功能提供了更丰富的用户界面,但你应该考虑你的用户是否的确需要富图形界面,尽管WPF有这样那样的问题,但在UI设计,特别是自定义风格和控件

改善WPF应用程序性能的10大方法 (转发)

WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势. 程序性能改善不是一蹴而就的,好的设计可以消除影响性能的问题,例如,在运行时构造对象就会对程序的性能造成影响.虽然WPF通过增强的导航等功能提供了更丰富的用户界面,但你应该考虑你的用户是否的确需要富图形界面,尽管WPF有这样那样的问题,但在UI设计,特别是自定义风格和控件

提高ASP.NET应用程序性能的十大方法

一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的系统具有扩展性,也可以减少数据库服务器响应请求的工作量. 如果你是用动态的SQL语句来返回多个数据集,那我建议你用存储过程来替代动态的SQL语句.是否把业务逻辑写到存储过程中,这个有点争议.但是我认为,把业务逻辑写到存储过程里面可以限制返回结果集的大小,减小网络数据的流量,在逻辑层也不用在过滤数据,

深入理解计算机系统之程序的机器级表示部分学习笔记

不论我们是在用C语言还是用JAVA或是其他的语言编程时,我们会被屏蔽了程序的机器级的实现.机器语言不需要被编译,可以直接被CPU执行,其执行速度十分  快.但是机器语言的读写性与移植性较高级语言低.高级语言被编译后便成为了汇编语言,汇编语言十分接近机器语言.之后汇编代码会转化为机器语言.虽然现代  的编译器能帮助我们将高级语言转化为汇编语言,解决了不少问题,但是对于一个严谨的程序员来说,需要做到能够阅读和理解汇编语言.我们主要围绕Intel来讲  解. 一  Intel处理器的历史演变 Inte

优化iOS程序性能的25个方法

1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为你管理retain和release的过程,所以你就不必去手动干预了.忘掉代码段结尾的release简直像记得吃饭一样简单.而ARC会自动在底层为你做这些工作.除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存. 现在所有的iOS程序都用ARC了,这条可以忽略. 2. 在

浅谈优化程序性能(上)

前言 我们知道,多项式定义为: 在几何学中,多项式是最简单的平滑曲线.简单是指它仅由乘法及加法构成,平滑是因为它类同口语中的平滑,以数学术语来说,它是无限可微,即它的所有高次微分都存在.事实上,多项式的微分也是多项式.简单及平滑的特点,使多项式在数值分析.图论,以及电脑绘图等,都发挥极大的作用.多项式求值是解决许多问题的核心技术.以数值分析为例,多项式函数常常用作对数学库中的三角函数求近似值. 现在,让我们来用 C 语言写一个对多项式求值的函数吧. 直接的算法 直接按照多项式的定义使用循环求值: