Memory Hierarchy / Program Optimization(程序优化)

本文探讨了程序优化的关键技术和方法,包括利用内存层次结构、提高局部性、使用优化编译器、指令级并行等手段提升程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.youkuaiyun.com/c602273091/article/details/53606031

Memory

Memory Intro

volatile

这里写图片描述

non-volatile

这里写图片描述

Disk

磁盘容量:
这里写图片描述

传输特定扇区的数据的过程:
这里写图片描述

计算传输某个扇区所需的时间:
这里写图片描述

Locality

CPU和memory之间的吞吐量相差巨大。
这里写图片描述

这时候是局部性使得这两者间的鸿沟没有那么大。局部性就是程序倾向于使用与它最近使用过的数据和指令。局部性设计时间局部性和空间局部性。时间局部性就是最近使用过的数据或者指令有较大可能性会被重新使用。空间局部性就是指最近使用过的数据或者指令周围的数据或指令有较大的可能性被用到。

举一个例子:
这里写图片描述

那么我们如何衡量一个程序使用有局部性?请看下面的memory hierarchy。

memory hierarchy

这里写图片描述

从上图可以看出,CPU是首先从cache读取数据,所以在局部性设计方面,我们先从cache入手。

这里写图片描述

具体怎么做呢?请看CMU 18-600的cache memory这一节以及结合cache lab你就有充分的了解 Click Here

Program Optimization

Optimization Compilers

优化编译器涉及寄存器分配,代码调度。消除dead code。
看一个例子:
这里写图片描述
这样做就可以减少stall,并且不会改变它的整个逻辑流,最后各个寄存器的值都是一样的。

一般做编译机优化有资源、过程的约束。画出data flow graph可以对这个过程调度可以认识更加清晰。
这里写图片描述

所以编译器做优化一般使用的方法是代码搬移,在寄存器级别就是寄存器重命名。重命名就是在有stall这种情况下使用一些空闲的寄存去以减少程序的暂停。
这里写图片描述

以上方法会导致有时候一个寄存器的赋值需要很多寄存器的参与,为了解决这个问题,所以使用一个中间变量复制。
这里写图片描述

常用的优化小技巧

代码搬移

把循环中重复计算的值搬出去,比如:
这里写图片描述

这里写图片描述

使用简单操作代替

这里写图片描述

共享相同变量

这里写图片描述

优化块

过程调用优化

之前:
这里写图片描述

之后:
这里写图片描述

代码混叠

这里写图片描述
这里写图片描述
每次都把b[i]的值加给自己,b[i]是数组,为了索引它还要计算地址。

修改:
这里写图片描述

使用指令级并行

根据处理器结构,进行代码优化。

举个例子:
使用vector数据结构索引数据:
这里写图片描述

对一个vector进行求和之类的操作:
这里写图片描述

修改如下,这样就不需要每次做一个边界检查了。其实我觉得这个和最早的去除过程调用意思一样。
这里写图片描述

supercsala:就是一个周期执行多条指令,从指令流取出一堆指令,然后以某一个顺序执行。

比如我们做一下操作,前后是有联系的:
这里写图片描述

那么我们可以一次乘以两个数:
这里写图片描述

这样的结果就是:
这里写图片描述
浮点数的结果还是没有优化。

请看下一个,只是修改了一点点:
这里写图片描述
谁让编译器是先做括号里面的呢。
这里写图片描述
结果就是:
这里写图片描述

对上面的代码还可以修改为:
这里写图片描述
这里写图片描述
这样就可以形成两个流了,在处理器处理load指令的时候,可以完美的连接。

SIMD

只需要执行一条指令,实现多个相同的指令。
这里写图片描述

解决跳转

使用预测,如果预测失败,再恢复。

PS:slide from CMU 18-600. Click Here

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值