程序局部原理性

CPU大多数时间在执行相同的指令或者与此相邻的指令,这就是程序局部性原理,依据此原理用来缓解CPU和内存之间的性能瓶颈。

内存

内存,从专业角度来讲,内存应该叫做DRAM,即动态随机存储器,内存存储颗粒芯片中的存储单元是由电容和相关元件做成,电容存储电荷的多、少代表数字信号0和1。

重点关注的是:内存的速度还有逻辑上内存和系统的连接方式和结构,如下图所示:

由上图可看出,控制内存刷新和内存读写的是内存控制器,而内存控制器集成在北桥芯片中。随着芯片制造工艺的提升,芯片集成度也越来越高,因此北桥芯片也集成到了CPU芯片中,这大大提升了CPU访问内存的性能。

CPU到内存性能的瓶颈

1、内存条的昂贵程度,超乎想象

2、CPU与内存条读写数据速度的差异:CPU要数据,内存一时给不了怎么办?CPU就得等,通常CPU会让总线插入等待时钟周期,直到内存准备好,就会发现,无论CPU新能多高都没用,内存才是决定系统整体性能的关键。

Cache

开头所讲到的程序的局部性原理:CPU 大多数时间在访问相同或者与此相邻的地址。就想到用一块小而块的存储器,放在CPU和内存之间,就可以利用程序的局部性原理来缓解CPU和内存之间的性能瓶颈。这小而块的存储器就是Cache,即高速缓存。

Catch中存放的是内存中的一部分数据,CPU在访问内存时先去访问Cache,若Cache中有需要的数据就直接从Cache中取出,若没有则需要从内存中读取数据,并同时写入Cache中,但也是由于程序局部性原理,在一段时间,CPU总能从Cache中读到自己想要的数据。

Cache可以集成在CPU内部,也可以做成独立的芯片放在总线上:

Cache主要由高速的静态存储器地址转换模块Cache行替换模块组成。

Cache 会把自己的高速静态储存器和内存分成大小相同的行,一行大小通常为 32 字节或者 64 字节。Cache 和内存交换数据的最小单位是一行,为方便管理,在 Cache 内部的高速储存器中,多个行又会形成一组。

Cache 大致的逻辑工作流程如下:

1、CPU 发出的地址由 Cache 的地址转换模块分成 3 段:组号行号行内偏移

2、Cache 会根据组号、行号查找高速静态储存器中对应的行。如果找到即命中,用行内偏移读取并返回数据给 CPU,否则就分配一个新行并访问内存,把内存中对应的数据加载到 Cache 行并返回给 CPU。写入操作则比较直接,分为回写和直通写,回写是写入对应的 Cache 行就结束了,直通写则是在写入 Cache 行的同时写入内存。

3、如果没有新行了,就要进入行替换逻辑,即找出一个 Cache 行写回内存,腾出空间,替换行有相关的算法,替换算法是为了让替换的代价最小化。例如,找出一个没有修改的 Cache 行,这样就不用把它其中的数据回写到内存中了,还有找出存在时间最久远的那个 Cache 行,因为它大概率不会再访问了。

Cache带来的问题

虽然Cache带来了性能方面的提升,但同时也给硬件和软件开发开来了问题,那就是数据一致性问题

X86 CPU的Cache结构图:

这是一颗最简单的双核CPU,具有三级Cache,第一级Cache是指令和数据分开的,第二级Cache是独立于CPU核心的,第三级Cache是所有CPU核心共享的

Cache的一致性问题主要包括三个方面:

1、一个 CPU 核心中的指令 Cache 和数据 Cache 的一致性问题。

2、多个 CPU 核心各自的 2 级 Cache 的一致性问题。

3、CPU 的 3 级 Cache 与设备内存,如 DMA、网卡帧储存,显存之间的一致性问题。

为解决上述问题,硬件工程师们开发了多种协议,典型的多核心Cache数据同步协议有MESI和MOESI,这里讲解下MESI协议。

Cache的MESI协议

MESI协议定义了4中基本状态:M、E、S、I,即修改(Modified)、独占(Exclusive)、共享(Shared)和无效(Invalid)

1、M 修改(Modified)

当前 Cache 的内容有效,数据已经被修改而且与内存中的数据不一致,数据只在当前 Cache 里存在。比如说,内存里面 X=5,而 CPU 核心 1 的 Cache 中 X=2,Cache 与内存不一致,CPU 核心 2 中没有 X。

2、E 独占(Exclusive)

当前 Cache 中的内容有效,数据与内存中的数据一致,数据只在当前 Cache 里存在;类似 RAM 里面 X=5,同样 CPU 核心 1 的 Cache 中 X=5(Cache 和内存中的数据一致),CPU 核心 2 中没有 X。

3、S 共享(Shared)

当前 Cache 中的内容有效,Cache 中的数据与内存中的数据一致,数据在多个 CPU 核心中的 Cache 里面存在。例如在 CPU 核心 1、CPU 核心 2 里面 Cache 中的 X=5,而内存中也是 X=5 保持一致。

4、I 无效(Invalid)

当前 Cache 无效。前面三幅图 Cache 中没有数据的那些,都属于这个情况。

Cache 硬件,它会监控所有 CPU 上 Cache 的操作,根据相应的操作使得 Cache 里的数据行在上面这些状态之间切换。Cache 硬件通过这些状态的变化,就能安全地控制各 Cache 间、各 Cache 与内存之间的数据一致性了。

开启Cache

x86 CPU 上默认是关闭 Cache 的,需要在 CPU 初始化时将其开启。

在 x86 CPU 上开启 Cache 非常简单,只需要将 CR0 寄存器中 CD、NW 位同时清 0 即可。CD=1 时表示 Cache 关闭,NW=1 时 CPU 不维护内存数据一致性。所以** CD=0、NW=0 的组合**才是开启 Cache 的正确方法。

开启 Cache 只需要用四行汇编代码,代码如下:

mov eax, cr0
;开启 CACHE
btr eax,29 ;CR0.NW=0
btr eax,30 ;CR0.CD=0
mov cr0, eax

获取内存视图

作为系统软件开发人员,与其了解内存内部构造原理,不如了解系统内存有多大。这个作用更大。

给出一个物理地址并不能准确地定位到内存空间,内存空间只是映射物理地址空间中的一个子集,物理地址空间中可能有空洞,有 ROM,有内存,有显存,有 I/O 寄存器,所以获取内存有多大没用,关键是要获取哪些物理地址空间是可以读写的内存。

物理地址空间是由北桥芯片控制管理的,那我们是不是要找北桥要内存的地址空间呢?当然不是,在 x86 平台上还有更方便简单的办法,那就是 BIOS 提供的实模式下中断服务,就是 int 指令后面跟着一个常数的形式。

由于 PC 机上电后由 BIOS 执行硬件初始化,中断向量表是 BIOS 设置的,所以执行中断自然执行 BIOS 服务。这个中断服务是 int 15h,但是它需要一些参数,就是在执行 int 15h 之前,对特定寄存器设置一些值,代码如下。

_getmemmap:
xor ebx,ebx ;ebx设为0
mov edi,E80MAP_ADR ;edi设为存放输出结果的1MB内的物理内存地址
loop:
mov eax,0e820h ;eax必须为0e820h
mov ecx,20 ;输出结果数据项的大小为20字节:8字节内存基地址,8字节内存长度,4字节内存类型
mov edx,0534d4150h ;edx必须为0534d4150h
int 15h ;执行中断
jc error ;如果flags寄存器的C位置1,则表示出错
add edi,20;更新下一次输出结果的地址
cmp ebx,0 ;如ebx为0,则表示循环迭代结束
jne loop ;还有结果项,继续迭代
ret
error:;出错处理

上面的代码是在迭代中执行中断,每次中断都输出一个 20 字节大小数据项,最后会形成一个该数据项(结构体)的数组,可以用 C 语言结构表示,如下。

#define RAM_USABLE 1 //可用内存
#define RAM_RESERV 2 //保留内存不可使用
#define RAM_ACPIREC 3 //ACPI表相关的
#define RAM_ACPINVS 4 //ACPI NVS空间
#define RAM_AREACON 5 //包含坏内存
typedef struct s_e820{
u64_t saddr; /* 内存开始地址 */
u64_t lsize; /* 内存大小 */
u32_t type; /* 内存类型 */
}e820map_t;

操作系统 -- Cache和内存的更多相关文章

  1. 操作系统实战45讲笔记- 07 Cache与内存:程序放在哪儿?

    程序局部性原理: CPU 大多数时间在执行相同的指令或者与此相邻的指令 时间局部性VS空间局部性: a. 时间局部性:当前访问的指令或数据,也可能在之后访问: b. 空间局部性:当程序访问内存地址x时 ...

  2. (转)CPU Cache与内存对齐

    转自:http://blog.csdn.net/zhang_shuai_2011/article/details/38119657 原文如下: 一. CacheCache一般来说,需要关心以下几个方面 ...

  3. 轻量级操作系统FreeRTOS的内存管理机制(一)

    本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu)供稿. 近几年来,FreeRTOS在嵌入式操作系统排行榜中一直位居前列,作为开源的嵌入式操作系统之一,它支持许多不同架构的处理器以及多种编译 ...

  4. ARM Cortex-A53 Cache与内存的映射关系以及Cache的一致性分析

    ARM Cortex-A53 Cache与内存的映射关系以及Cache的一致性分析 题记:如果文章有理解不对的地方,欢迎大家批评指正,谢谢大家. 摘要:本文以Cortex-A53为例,首先分析Cach ...

  5. Memory Ordering (注意Cache带来的副作用,每个CPU都有自己的Cache,内存读写不再一定需要真的作内存访问)

    Memory Ordering   Background 很久很久很久以前,CPU忠厚老实,一条一条指令的执行我们给它的程序,规规矩矩的进行计算和内存的存取. 很久很久以前, CPU学会了Out-Of ...

  6. android中图片的三级缓存cache策略(内存/文件/网络)

    实现图片缓存也不难,需要有相应的cache策略.这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且 ...

  7. python1--计算机原理 操作系统 进制 内存分布

    本周内容   '''第一天: 计算机原理 操作系统  第二天: 编程语言 python入门:环境 - 编辑器 变量 基本数据类型 '''``` ## 学习方法 ```python'''鸡汤 - 干货 ...

  8. 解决linux buffer/cache 消耗内存过高引发的问题

    工作中接到DBA报障某台服务器 跑一些大的数据,服务器就无法远程连接,报错,抓过日志叫DELL工程师检测也没问题,系统也重装过, 现在些一些较大的数据就会报如 图错误,由于服务器远在异地城市IDC机房 ...

  9. cache和内存

    CPU与内存 北桥:主桥,主要用来处理高速信号,负责与处理器的联系:CPU通过FSB前端总线来访问内存控制器. 南桥:IO桥,负责IO总线之间的通信,比如PCI总线.SATA.USB等,可以连接光驱. ...

  10. cache和内存屏障

    1 cache简介 1.1 cache缓存映射规则 tag查看cache是否匹配,set index |tag |set index |block offset ||20-bit |7-bit |5b ...

随机推荐

  1. warning C291: not every exit path returns a value 在switch分支中使用return

    switch(data)                        {                          case   1:                            ...

  2. springboot+easypoi模板导出Excel 动态表头+多表格(一个sheet)

    1.需求:将此页面的几个表格导出 其中表头中的仓库 集散地是是动态生成的. 首先制作Excel模板: 代码: @Resource private RedisService redisService; ...

  3. 文件快递柜FileCoxBox-匿名口令分享文本,文件,像拿快递一样取文件

    FileCoxBox特色 轻量简洁:Fastapi+Sqlite3+Vue2+ElementUI 轻松上传:复制粘贴,拖拽选择 多种类型:文本,文件 防止爆破:错误次数限制 防止滥用:IP限制上传次数 ...

  4. 推荐一款最新开源,基于AI人工智能UI自动化测试工具!支持自然语言编写脚本!

    随着互联网技术的飞速发展,Web应用越来越普及,前端页面也越来越复杂.为了确保产品质量,UI自动化测试成为了开发过程中不可或缺的一环.然而,传统的UI自动化测试工具往往存在学习成本高.维护困难等问题. ...

  5. 结构化语句header nav aside main article section footer

    点击查看代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  6. linux curl 测试 websocket 服务

    如下 curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: ec ...

  7. godoc使用方法介绍

    一.go doc简介 Godoc是go语言的文档化工具,类似于文档化工具godoc,类似于Python的Docstring和Java的Javadoc Godoc通过解析包含注释的Go代码来生成HTML ...

  8. vue学习二(计算属性computed和监听器watch)

    1.1.computed  计算属性 先写注意事项把:computed和methods的区别 //computed定义的方法我们是以属性访问的形式调用的{{computedTest}}    comp ...

  9. pandas -- 处理非数值型数据 -- 数据分析三剑客(核心)

    博客地址:https://www.cnblogs.com/zylyehuo/ 开发环境 anaconda 集成环境:集成好了数据分析和机器学习中所需要的全部环境 安装目录不可以有中文和特殊符号 jup ...

  10. Nginx配置跨域,覆盖后端服务跨域配置

    本篇文章主要介绍了,如何通过Nginx配置跨域,并覆盖后端服务跨域配置. 先看下后端代码跨域配置: 主要的目标是:不修改后端跨域配置代码,来实现Nginx跨域指定域名. @Bean public Co ...