计算机原理—缓存

一、计算机的存储层次

计算机的居于主导的硬件是CPU,但正如俗话所讲"一个好汉三个帮",光有CPU啥也干不了。所以就需要有支撑的其它硬件,而在这其中,重要的就是存储单元。CPU要想发挥计算能力就需要与外界进行数据的交互,而数据的交互就无法离开数据存储单元。为了保障数据的快速读写和交换,计算机一般将存储单元划分成几个层次来分别满足不同情况下的应用。它们主要包括:

  1. 缓存
    在CPU中,它可以划分成L1,L2,L3甚至可以定义更多的层次。所以其一般也叫做片上缓存。它的特点就是容量较小,但读写速度极快,访问延迟也很低,掉电后数据也会自动丢失
  2. 内存
    也叫主存,主要是提供非掉电情况下的数据高速读写,它可以和上面的缓存形成一个级别调用的数据读写机制。它的特点是容量很大,读写速度相对较快,访问延迟比缓存要慢一个量级,但在掉电后数据会自动丢失
  3. 硬盘
    硬盘又可以分为机械硬盘和固态硬盘,甚至在硬盘内部又有缓存。最新的固态硬盘,速度已经在向内存的数据读写速度逼近(当然,成本也高)。它的特点是容量超大,访问延迟非常高,但数据在掉电的情况下也不会丢失

二、缓存

从上面的存储层次可以看到,为了匹配CPU高速的数据处理能力与内存自身速度较低的现实,才出现了缓存机制。由此大家可以推想过去,单纯在软件层次也会出现类似的应用场景,所以缓存不单纯只在硬件中存在,在软件中缓存也被大量应用。并根据相关的具体应用,衍生出了众多的框架和库等。

早期的硬件缓存分为片外和片上缓存,但片外的缓存由于数据交互成本较高(总线速度、时间周期等)目前基本已经被淘汰了。另外,随着片上缓存的价格不断降低,已经解决了片上缓存的成本问题。

至于软件层次的缓存,其主要目的仍然与硬件缓存一样,主要就是为了提高数据读写的速度。在此基础上,通过合理的成本考量,来实现特定的目的,比如典型的Redis数据库和memcached等软件。

缓存的一个典型的特征就是:它对应用一般来说是透明的。即对开发者来说,不能因为缓存机制的引入导致整体开发难度的上升。缓存的运行(以硬件不例)一般分为以下几步:

  1. 缓存查找,CPU首先在L1中查找
  2. 缓存命中,CPU直接应用数据
  3. 缓存未命中,逐级向L2,L3直到主存查找,直到找到
  4. 缓存加载,从查找到的存储单元中加载到缓存
  5. 缓存的替换,缓存有一套成熟的淘汰策略,可以参看"操作系统"中的内存相关知识

大家可以用下面的代码简单查看缓存机制:

c 复制代码
// Linux系统
#include <iostream>
#include <fstream>
#include <string>

void getCacheInfo() {
    std::ifstream fd("/proc/cpuinfo");
    std::string line;
    
    while (std::getline(fd, line)) {
        if (line.find("cache size") != std::string::npos) {
            std::cout<<"core:" << line << std::endl;
        }
    }
}

三、缓存的原理

为什么会有缓存?重要的原因就是CPU、内存、硬盘等存储器的读写速度和容量大小不匹配。而它们的更本质的原因在于这些硬件的成本因为上述功能导致差别巨大。而为了让这几种存储器能够进行匹配,就可以使用缓存机制来实现某种概率下的适配。而缓存产生的一个根本原因在于"计算机访问的局部性(时间和空间的局部性)",这点相信开发者大多都明白。这才是缓存得到广泛应用的原理。

另外,技术的限制也是一个不可忽视的原因。比如缓存一般不能进行数据的持久化。这就导致缓存的应用面受到限制。这一点在单纯的软件应用中,也体现的较为明显。虽然在不少的缓存应用软件中,或多或少都增加了缓存的持久化机制,但其应用一般是为了最底层的数据安全机制原因而不是为了缓存的效率而出现的。

为了实现缓存的数据管理,特别是随着硬件技术的不断的发展(多CPU,多核等),缓存数据交互也成为了一种强需求,所以MESI等缓存一致性协议就出现了。它能够保证所有的CPU核心看到的相同的内存地址的数据是一致的。MESI在前面文章中分析过,此处不再赘述。

四、缓存和内存

CPU的Cache和内存的关系其实是缓存应用中的一个最典型的用法。CPU的运行速度远超过内存读写速度N个量级。也就是说,CPU如果直接操作内存会导致大量的时钟周期的浪费,如果使用高速缓存则可以在二者间搭建一个快速数据交互的桥梁。

五、总结

缓存机制是一种在计算机技术中应用非常广泛的技术。不管是在硬件还是软件应用中,都直到了重要的作用。特别在互联网的应用中,缓存机制是一种不可或缺的应用。开发者只要掌握了缓存机制的原理则对其应用就很容易掌握。至于缓存在什么情况下应用,这就需要开发者根据自己的场景来判断,不能想当然的决定。

相关推荐
利刃大大8 小时前
【高并发服务器】十二、LoopThreadPool线程池管理模块
服务器·c++·项目
Summer_Uncle8 小时前
【C++学习】对象特性--继承
开发语言·c++·学习
艾莉丝努力练剑9 小时前
【Git:基本操作】深度解析Git:从初始Git到熟悉基本操作
大数据·linux·c++·人工智能·git·gitee·指令
苦学编程的谢9 小时前
Redis_2_特性介绍+应用场景
数据库·redis·缓存
CN-Dust10 小时前
【C++】2025CSP-J第二轮真题及解析
开发语言·c++·算法
仟濹10 小时前
「经典图形题」集合 | C/C++
c语言·开发语言·c++
乙己40711 小时前
设计模式——单例模式(singleton)
java·c++·单例模式·设计模式
蓝色 - Lanse11 小时前
模型推理如何利用非前缀缓存
人工智能·缓存
嵌入式小李.man12 小时前
linux中多路复用IO:select、poll和epoll
linux·c++