博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《深入理解计算机系统》 优化程序性能的几个方法
阅读量:6984 次
发布时间:2019-06-27

本文共 2004 字,大约阅读时间需要 6 分钟。

本文几个优化程序性能的方法出自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

 

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

你可能感兴趣的文章
美国税局再遭攻击:原是偷来的社会安全号码作祟
查看>>
六大技巧提升员工信息安全意识
查看>>
保利协鑫多晶硅产量再创历史记录
查看>>
爱屋及乌 年轻投资者因喜爱Snapchat亏钱也买Snap股票
查看>>
物联网产品背后潜藏着危机
查看>>
阿里云将增设马来西亚数据中心 中国技术获赞
查看>>
与Netflix合作 美电视运营商推出4K频道
查看>>
Struts2中的Action
查看>>
Balluff推出刀具识别系统
查看>>
美国支付巨头Verifone遭遇网络攻击
查看>>
开平推进智慧城市等领域信息化建设及公共数据资源共享
查看>>
宜兴电信成功跨界合作开拓农村物联网市场
查看>>
Oracle业务适合用PostgreSQL去O的一些评判标准
查看>>
多个常见代码设计缺陷
查看>>
今年光伏市场规模可达30GW 分布式有望占据三分江山
查看>>
因新漏洞问题 Firefox 49发布时间将延期一周
查看>>
WLAN产品形态之分层架构
查看>>
Chrome 隐藏 SSL 证书信息 禁止禁用 DRM
查看>>
AngularJS 的自定义指令
查看>>
《CCNA ICND2(200-101)认证考试指南(第4版)》——第1章定义生成树协议
查看>>