局部性原理的理解

2024-06-23 06:18
文章标签 理解 原理 局部性

本文主要是介绍局部性原理的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

局部性原理的理解

17300240036 杜逸闲

本文首先介绍了局部性原理的定义,然后列举了一些局部性原理的应用,接着具体讨论了局部性原理在page coloring中的应用,最后分析了局部性原理的本质。

什么是局部性原理

在计算机学科的概念中,局部性原理是一个常用的术语,指处理器在访问某些数据时短时间内存在重复访问,某些数据或者位置访问的概率极大,大多数时间只访问局部的数据。主要可以分为时间局部性和空间局部性两种。

时间局部性

如果一个数据正在被访问,那么在近期它很可能还会被再次访问。任何编写过程序的人都知道,这个原理是正确的。我们在编写程序时,总是在一段时间内(比如一个循环或者一个函数内)对相同的地址进行反复的操作。

但为什么人们在编写程序的时候不会先计算出一个数据,将其存放在某个地方,然后在很长一段时间内都不使用呢?Locality Principle 一文提到这是因为人类解决问题的思维方式是分治(divide and conquer),将大事化小,小事化了。一个很庞大的问题会被分解成若干个子问题,在各自的模块分别解决,而某一个子问题涉及到的数据会在存放后不久被读取。

空间局部性

在不久的将来将用到的数据很可能与现在正在使用的数据在空间地址上是临近的。
这条原理的原因也同样是因为分治的思想。当一个模块正在解决一个子问题时,他会申请使用很多局部变量,这些变量在空间上连续,同时在逻辑上也有关联。因此正在使用的这个数据地址旁边的数据,当然也是很可能被用到的。

局部性原理的应用

局部性原理最先在操作系统领域被发现且应用,但慢慢延申至计算机科学的其他领域。最主要的应用就是在各种缓存的replacement algorithm中。下面列举一些其应用的例子:

  1. 操作系统中,在将虚拟内存转换到物理内存的过程中,我们需要用到TLB。在交换页至硬盘时,内存可以看作是硬盘的一种缓存。在缓存的replacement algorithm中我们会应用到局部性原理。
  2. CPU的多级缓存技术。
  3. 数据库中的memcache。当使用关系型数据库(如mysql时),即使我们分库分表储存,高峰期单机的查询压力还是很大。由于查询的项同样有局部性,此时可以使用如redis一类的kv数据库做memchache。
  4. 计算机网路中的CDN。由于同一个用户,甚至同一个地区的用户,在访问的数据上都存在局部性。大型的网站都引入了CDN来帮助分散主机的压力。CDN可以看作是服务器的一个cache。
  5. CopyOnWrite. 在Linux的fork中,子进程应该拥有独立的地址空间,父进程拥有的数据也应该复制一份。但由于局部性原理的存在,只有一小部分的数据是会被修改的,而大部分数据是只需要读的,有的数据甚至不会被使用。因此只有当子进程写数据时,这块数据才会被真正的复制。

page coloring与局部性原理

缓存的架构

我们知道,在CPU的cache中会缓存一些内存,其中缓存的组织方式分别有三种,VIVT、VIPT和PIPT,见下图:在这里插入图片描述
而在实际使用中,因为VIPT的效率比较高,我们会使用VIPT架构。VIPT架构使用虚拟地址做索引,物理地址做Tag。在利用虚拟地址索引cache同时,同时会利用TLB将虚拟地址转换为物理地址。然后将转换后的物理地址,与虚拟地址索引到的cache line中的Tag作比较,如果匹配则命中。

但这种方式由于仍然拿虚拟地址做索引,仍然会出现cache alias问题。

cache alias

cashe alias是指,当两个不同的虚拟地址都映射至同一个物理地址时,他们在cache中可能不存在于同一个cache line中。那么当其中一个地址中储存的值被修改时,另一个cache line就会有失效的问题,要解决这个问题会严重影响效率,因此应当避免cache alias出现。

下面我们将举例说明在VIPT架构下什么时候会出现cache alias。

假设页大小为4KB。对于不同的两个VA和他们映射的同一个PA,他们的offset即最低的12位bit[0…11]一定是相同的。在使用虚拟地址查找cache line的组时,若能保证用于索引的虚拟地址的位数在bit[0…11]中,就能确保两个虚拟地址查找到同一个cache line组内。而由于我们并行地在TLB中查询到了PA,并用这个PA作为tag在这个cache line组内查找,这两个VA最终会查找到同一个cache line内,不会出现cache alias.

假设cache大小为16KB,4路组相联,cache line大小为32(5个bit)。此时我们需要虚拟地址的7个bit作为索引,而由于cache line大小为32,占据了bit[0…4],为了对齐我们只能用bit[5…11]作为索引。而由于两个VA的bit[0…11]都是相同的,他们都会被映射到同一个cache line组内,不会出现cache alias.

但假设现在cache大小为32KB,其余条件不变。此时我们就需要虚拟地址的7个bit作为索引,同理为了对其我们需要用bit[5…12]作为索引,而两个VA的bit[12]可能并不一样,这就导致他们被索引到不同的组内,占用了两个不同的cache line,导致了cache alias.

如何解决cache alias

其实方法的原理很简单。只要保证这两个VA用作映射的bit都是一样的,就可以保证他们映射到同一个组内。那么我们只要在建立VA到PA的映射时,强制让VA和PA的一定数量的低位保持一致即可。

如上一节的第一个例子,操作系统不需要做任何工作,VA和PA的最低12位必定一样,因此在mapping时不需要额外操作。

而第二个例子中,我们便需要保证VA和PA的bit[12]是一致的。比如VA的bit[12]是1,我们就只会将其分配到bit[12]为1的PA上,而不将其分配到bit[12]为0的PA上。用一种比喻的手法来说,PA和VA都拥有了0和1两种颜色,只有颜色一样的page才有可能建立虚拟地址到物理地址的映射。

这就是所谓的page coloring.

与局部性原理的关系

page coloring可能会导致一个问题。那就是内存和缓存的利用率可能下降。假设我们的page拥有四种颜色。此时cache line组实际上会被分成四种颜色。考虑下面一种情况,所有的VA的颜色均为0. 在这种情况下,分配的所有PA的颜色也为0. 这会导致更多的物理内存分配失败,需要更多的交换,从而带来更多的缺页,严重影响了效率。同时,由于只有颜色为0的cache line组被使用,缓存命中率会降低,效率又会大打折扣。

实际上,由于空间局部性原理,一段程序在一定时间内总是会使用相邻的一段内存,也就是说,VA和PA的颜色应该是在四种颜色中均匀分布的。上述问题在实际中并不会存在,或不会造成什么可观的影响。

局部性原理的本质

从物理的视角看,局部性原理的本质是熵的不均匀。不同事物的熵有高有低,熵低的事物组织性更强,这一组事物中的联系更紧密。而局部性原理认为在时间上或者空间上距离近的事物他们的联系更强,因此熵更低,暗示我们将他组织在一起。

从数学的角度上考虑,局部性原理的本质,就是一部分事情发生的概率与另一些事情发生的概率不相等。比如空间局部性指的是,与当前正在使用的内存在空间中相邻的部分,接下来被使用的概率比离得远得更大。
在自然界中,不存在完美的平均分布。实际上自然界中大量事物发生的概率都遵循泊松分布。局部性原理其实就是对泊松分布的一个应用。
在这里插入图片描述
如果定义x=k为距离当前被访问资源距离为k的资源被访问。那么当k越小时,p(x=k)越大,我们就应该将距离尽可能近的资源提前加载。

认识局部性原理的本质的意义在于什么呢?如果意识到狭义上的局部性原理只是泊松分布的一个应用,那么当一些事情发生的概率并不符合泊松分布时,狭义上的局部性原理就需要修改。或者我们需要对其中的k做出一些变换,使得其服从泊松分布。具体到实际应用中,我们不能奉狭义上的局部性原理为真理,而在这个优化方向上蒙蔽了双眼,错过了可优化的空间。

这篇关于局部性原理的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086357

相关文章

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

Spring IOC核心原理详解与运用实战教程

《SpringIOC核心原理详解与运用实战教程》本文详细解析了SpringIOC容器的核心原理,包括BeanFactory体系、依赖注入机制、循环依赖解决和三级缓存机制,同时,介绍了SpringBo... 目录1. Spring IOC核心原理深度解析1.1 BeanFactory体系与内部结构1.1.1

MySQL 批量插入的原理和实战方法(快速提升大数据导入效率)

《MySQL批量插入的原理和实战方法(快速提升大数据导入效率)》在日常开发中,我们经常需要将大量数据批量插入到MySQL数据库中,本文将介绍批量插入的原理、实现方法,并结合Python和PyMySQ... 目录一、批量插入的优势二、mysql 表的创建示例三、python 实现批量插入1. 安装 PyMyS

GO语言zap日志库理解和使用方法示例

《GO语言zap日志库理解和使用方法示例》Zap是一个高性能、结构化日志库,专为Go语言设计,它由Uber开源,并且在Go社区中非常受欢迎,:本文主要介绍GO语言zap日志库理解和使用方法的相关资... 目录1. zap日志库介绍2.安装zap库3.配置日志记录器3.1 Logger3.2 Sugared

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

深入理解MySQL流模式

《深入理解MySQL流模式》MySQL的Binlog流模式是一种实时读取二进制日志的技术,允许下游系统几乎无延迟地获取数据库变更事件,适用于需要极低延迟复制的场景,感兴趣的可以了解一下... 目录核心概念一句话总结1. 背景知识:什么是 Binlog?2. 传统方式 vs. 流模式传统文件方式 (非流式)流

深入理解Go之==的使用

《深入理解Go之==的使用》本文主要介绍了深入理解Go之==的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录概述类型基本类型复合类型引用类型接口类型使用type定义的类型不可比较性谈谈map总结概述相信==判等操作,大

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS