今天是个好天气 logo 今天是个好天气
  • Home
  • Go
  • MySQL
  • Redis
  • LeetCode
  • Hello World
↩️README 网络发展过程 键入url到渲染显示 HTTP报文 HTTPS / HTTP1、2、3 三次握手/四次挥手 socket 可靠的TCP IP知识全家桶 ping的工作原理 优化程序性能 存储器 链接 进程、线程、调度 问题 虚拟内存 配个环境 Git Shell Docker python

存储器

内存和磁盘

image-20230204200617142

随机访问存储器

简称RAM,分为SRAM (static RAMS) 和DRAM(Dynamic RAM)。

SRAM:只要供电,SRAM就会保持不变,不需要刷新,存取更快,对光和磁不敏感,但是价格贵,主要用于cache,TLB。

由一种双稳态的存储器单元构成。


DRAM:是敏感的,成本较低,访问时间长,主要用于主存。

多个DRAM芯片被封装在内存模块中,与内存管理器连接。

DDR4,数字表示是预取缓存区的大小,16比特。

LP,Lower Power,低性能,在手机、商务本中使用。

磁盘

磁盘由盘片构成,每个盘片上表面又划分成多个磁道,磁道又划分成对应的扇区。

磁盘操作是通过主轴旋转找到对应的扇区,通过传动臂选择合适的磁道,然后通过读写头读取数据。

固态硬盘

Solid State Disk,SSD。是由半导体存储器构成,没有移动的不见。读写速度更快,但是反复读写也会造成闪存块的破损,从而导致SSD磨损。

局部性

一个编写良好的计算机程序常常具有良好的局部性,指的是倾向于引用邻近于其他最近引用过的数据项本身。

它们倾向于引用邻近于其他其他最近引用过的数据项的数据项。

  • 时间局部性:在一个具有良好时间局部性的程序中,被引用过的一次的内存位置很可能在不远的将来再被多次引用。我们希望在一次不命中后缓存,在之后的访问命中能够比当初不命中快很多。

  • 空间局部性:在一个具有良好空间局部性的程序中,被引用过的一次的内存位置很可能在不远的将来引用附近的一个内存位置。我们希望在不命中后,缓存块中的多个数据对象,在之后访问命中可以弥补当初复制该块的开销。

利用局部性原理,计算机设计可以通过引入被称为高速缓存存储器的小而快速的存储器作为最近引用过的指令和数据项。

类似的,Web浏览器缓存部分最近使用的文档,到时候优先访问前端磁盘高速缓存中。

在数组中,数据是按照行来存储的,因此按照行的顺序遍历速度大于按照列的遍历速度,这是一种空间局部性优劣的表现。

程序指令存放在内存中当中,一般不会修改,便于CPU读取,体现了良好的空间的局部性。

存储器的缓存

一般而言,高速缓存(cache)是一个小而快速的存储设备,他作为存储在更大,也更慢的设备中的数据对象的缓冲区当中。使用cache的过程称为缓存。

存储器层次结构的中心思想是:对于每个k层的更快的更小的存储设备,应该作为k+1层更慢更大的存储设备的缓存。例如:本地磁盘作为远端服务器磁盘的缓存,内存缓存磁盘中的程序指令。

  • 每一层结构被划分成多个数据对象组块,称为块(block)。
  • 数据总是以块为传送单元在不同层之间复制传输的。
  • 任何相邻层之间传输的块的大小是固定的。

缓存命中

第k层中存放了第k+1层中需要的数据对象d时,我们访问第k层获取d,称为缓存命中。访问第k层的速度是大于第k+1层的。

缓存不命中

同上,当出现缓存不命中时,会去k+1层获取数据对象,并复制到k层,当缓存满时,需要根据缓存的替换策略来控制替换那个块,常见的有LRU。

缓存不命中的种类

当发生缓存不命中时,第k层需要执行某个放置策略,考虑把数据从k+1中取出放置到k层哪个位置。

当第k层为空时,发生的不命中称为强制性不命中。

采用一定规则放置时,但是可能导致不同的数据块映射到同一个区域,从而导致冲突不命中。

CPU倾向于访问一个固定的工作集,当这个工作集大小超过缓存大小时,会导致容量不命中。

最灵活的方式是任意的放置。但是再访问时定位代价较高。

高速缓存存储器

由于CPU和主存之间存在着较大的性能差异,因此又在CPU和主存之间插入了三个级别的高速缓存。

CPU如何判断读取的字节在高速缓存中命中

  1. 由组索引找到对应的高速缓存组
  2. 根据标记位确定所在的行
  3. 最后根据设置的有效位和对应地址的标记位 匹配,再加上块偏移找到在对应数据块中的位置

直接映射高速缓存

每一个组只有一个行的高速缓存称为直接高速缓存。

对比上面的高速缓存,每一个组只有一个行,省去了行的匹配,此外在进行不命中时的行替换直接替换当前的行。

抖动

这样也可能会带来冲突不命中的问题,即使拥有足够的高速缓存空间,但是交替映射到了同一个组的块位置。

解决办法是留有一定字节的填充(申请更大的空间存放更多的数据)。

组相联高速缓存

相比前者,使得每一组的行数可以大于1,但是同时带来了缓存不命中时行替换的选择问题,最简单的替换策略是随机选择替换的行。

全相联高速缓存

一个组包含所有缓存行,不需要组索引位。

因为高速缓存电路必须并行地搜索许多相匹配的标记,构造一个又大又快的相联高速缓存困难且安规,因此全相联高速缓存只是适合做小的高速缓存,例如TLB。

高速缓存的其他特性

只保存指令的cache称为i-cache,只保存程序数据的高速缓存称为d-cache,二者都保存的称为unified cache。

有关写的问题

通常采用的方式是写回的策略,当发生写一个已经缓存的字时,通常是将高速缓存中的修改后,当块要被替换时,才会写入到低一层的存储当中,并不是立即直写。

编写有利于高速缓存的代码

  1. 处理好核心函数里的循环,大部分时间花在了少量的循环当中。
  2. 尽量减小每个循环内部的缓存不命中的数量。
  1. 内存和磁盘
    1. 随机访问存储器
    2. 磁盘
    3. 固态硬盘
  2. 局部性
  3. 存储器的缓存
    1. 缓存命中
    2. 缓存不命中
    3. 缓存不命中的种类
  4. 高速缓存存储器
    1. 直接映射高速缓存
    2. 组相联高速缓存
    3. 全相联高速缓存
  5. 高速缓存的其他特性
    1. 有关写的问题
    2. 编写有利于高速缓存的代码
Created by shixiaocaia | Powered by idoc
Think less and do more.