程序设计原则——局部性原理

本文探讨了程序设计中的局部性原理,解释了存储器层次结构,强调了高速缓存在性能优化中的作用。文章指出,良好的程序具有空间和时间局部性,建议通过优化循环结构、利用存储器的访问模式来编写高速缓存友好的代码,以减少存储器不命中率并提高程序性能。同时,文章还介绍了高速缓存的工作原理和不同类型的高速缓存映射方式,并通过实验展示了高速缓存对程序执行时间的影响。

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

存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构:CPU寄存器-》高速缓冲存储器-》主存储器-》磁盘-》通过网络连接的其他存储设备。

 

SRAM静态,一般作为高速缓冲存储器。

DRAM动态,一般作为大容量的主存储器

 

每次CPU和主存之间的数据传送都是通过一些列的步骤完成的,这些步骤称为总线事务。读事务从主存传送数据到CPU,写事务从CPU传送数据到主存。

 

局部性:一般较好的程序都有较好的局部性,也就是说,它们倾向于引用的数据项邻近于其他最近引用过的数据项,或者邻近于最近自我引用过的数据项。对应的就是空间局部性和时间局部性

 

局部性小结:

1、重复引用同一变量的程序有较好的时间局部性。

2、对于具有步长为k的引用模式的程序,步长越小,空间局部性就越好。具有步长为1的引用模式的程序有很好的空间局部性。在存储器中以大步跳来跳去的程序的空间局部性就很差。

3、对于取指令来说,循环有很好的空间和时间局部性。循环体越小,循环迭代次数越多,局部性越好。

 

编写高速缓存友好的代码

编写高速缓冲友好的代码的基本方法:

1、让最常见的情况运行得快。程序通常把大部分时间都花在少量的核心函数上,而这些函数通常把大部分时间都花在了少量的循环上。所以要把注意力集中在核心函数的循环上,而忽略其他部分。

2、在每个循环内部使缓存不命中数量最小。在其他条件,例如加载和存储的总次数相同的情况下,不命中率低的程序运行得更快。

 

注意:编译器将局部变量存储到寄存器中,因此循环内对局部变量的引用不需要任何加载或存储指令。

 

高速缓存对程序性能的影响:

### 存储器层次结构中的局部性原理 存储器层次结构的设计基于程序运行过程中表现出的 **局部性原理**。这一理论认为,在程序执行期间,处理器倾向于重复访问某些数据或指令集,而这些访问通常集中在较小的空间范围和较短的时间间隔内[^1]。 #### 时间局部性和空间局部性 - **时间局部性 (Temporal Locality)** 表示如果某个数据项被访问了一次,则它很可能在不久之后再次被访问。这种特性可以通过缓存机制加以利用,即将最近使用的数据保存在快速访问的存储设备中(如 CPU 缓存),以便后续访问能够更快完成。 - **空间局部性 (Spatial Locality)** 则指当某一位置的数据被访问时,其附近的其他数据也很可能随后会被访问到。因此,现代计算机系统会预取相邻区域的内容至高速缓冲区,从而减少频繁访问主存的需求。 由于不同级别的存储介质之间存在显著的速度差异——例如 SRAM 比 DRAM 快得多,但成本也更高;DRAM 又远胜于机械硬盘却不及固态驱动器 SSD ——所以形成了由多级组成的分层架构。该模型允许将最常使用的少量热数据放置于靠近处理单元处的小型高效暂存区内,而对于不那么紧急的大批量冷资料则分配给相对廉价低效的大规模永久储存装置上[^2]。 此外值得注意的是,尽管理想状态下人们期望获得无界限扩展能力且即时响应的理想化单一平面式随机存取记忆体(RAM),然而实际操作层面考虑到经济因素以及物理定律限制等因素影响下,建立分级式的混合解决方案成为必然选择。 对于具体实现细节而言,动态随机存取存储器(DRAM)之所以需要定期刷新是因为电容器随时间推移会发生泄漏现象,如果不及时补充电量的话就会丢失所保存的信息[D]。这正是选项B描述的情况:“每隔一定时间,需要根据原存内容重写一遍即刷新”。 综上所述,通过理解并应用局部性原则可以有效优化整个计算平台上的资源调度策略,进而提升整体性能表现水平。 ```python # Python 示例展示如何模拟简单的 LRU 缓存替换算法 from collections import OrderedDict class LRUCache: def __init__(self, capacity): self.cache = OrderedDict() self.capacity = capacity def get(self, key): if key not in self.cache: return -1 value = self.cache.pop(key) # 将最新访问过的键移动到最后面 self.cache[key] = value return value def put(self, key, value): if key in self.cache: self.cache.pop(key) elif len(self.cache) >= self.capacity: # 移除最早未使用的项目 self.cache.popitem(last=False) self.cache[key] = value cache = LRUCache(2) cache.put(1, 'Value1') cache.put(2, 'Value2') print(cache.get(1)) # 返回 Value1 并更新顺序 cache.put(3, 'Value3') # 超过容量驱逐掉最少使用的一项 print(cache.get(2)) # 已经被淘汰返回 -1 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值