设计 一个 CPU 的 存储管理部件
设计 一个 CPU 的 存储管理部件, 这个 题 留给 大家 思考 。
CPU 里 有 存储管理部件, 据说 以前 是 在 北桥 芯片 里 。
存储管理部件 的 功能 是 地址映射(页映射), 判断 对 内存 的 访问 是否 越界 。
对 内存 的 访问 越界 就是 一个 进程 的 代码 访问 了 另一个 进程 的 内存 , 这是 不允许 的 。
但 有些时候, 操作系统 允许 多个 进程 之间 共享 一块 内存, 比如 管道, 或者 共享内存 。 这 通常 用于 进程间 通信 或 传输数据 。
共享内存 允许 共享 这块 内存 的 多个 进程 访问, 存储管理部件 应该 也要 支持 这个 功能 。
实际上, 一级 Cache 有 自己 的 存储管理部件 , 二级 Cache 有 自己 的 存储管理部件 , 三级 Cache 有 自己 的 存储管理部件 , 虚拟内存 有 自己 的 存储管理部件 。
这里 的 一级 Cache 二级 Cache 三级 Cache 是 CPU 的 一级 Cache 二级 Cache 三级 Cache 。 虚拟内存 是 操作系统 的 虚拟内存 。
具体的 ,
一级 Cache 的 存储管理部件 的 功能 是 一级 Cache 和 虚拟内存 之间 的 地址映射(页映射), 以及 防止 内存 的 越界访问 。
二级 Cache 的 存储管理部件 的 功能 是 二级 Cache 和 虚拟内存 之间 的 地址映射(页映射), 以及 防止 内存 的 越界访问 。
三级 Cache 的 存储管理部件 的 功能 是 三级 Cache 和 虚拟内存 之间 的 地址映射(页映射), 以及 防止 内存 的 越界访问 。
虚拟内存 的 存储管理部件 的 功能 是 内存 和 虚拟内存 之间 的 地址映射(页映射), 以及 防止 内存 的 越界访问 。
每个 存储管理部件 都 维护 一份 页表 。
硬件上, 一级 Cache 的 存储管理部件 应该 在 一级 Cache 的 附近, 访问 一级 Cache 的 存储管理部件 和 访问 一级 Cache 一样快 。
其实 还有一个 页表, 维护 页 在 页文件 里 的 位置 。 这个 页表 称为 页文件页表 。
虚拟内存 将 常用 的 数据 保存 在 内存 里 , 不常用 的 数据 保存 在 硬盘 的 一个 文件 里, 这个 文件 就是 页文件 。
要 加载 一个 页 到 内存 时, 需要 知道 页 在 页文件 里 的 位置 。 页 可能 创建 、销毁, 为了 避免 页文件 无限扩大, 会 “重复利用” 页文件 的 空间 来 保存 页, 所以, 页文件页表 会 经常 添加 删除 插入 页表项, 而 查找 页文件页表 的 工作 可以 用 软件 的 方式 来 做 。 可以用 红黑树 二分法 来 做 。
但 按理, 页文件页表 也可以用 硬件 的 存储管理部件 来 实现, 再 增加 一个 存储管理部件 就可以 。 但 问题 是, 在 64 位 架构 下, 64 位 地址 有 4G * 4G = 16 EB 的 地址空间, 16 EB 除以 页 的 大小 就是 可能 的 页 的 数量, 这个 数量 是 很大 的, 虽然 实际 中 并不会 用到 那么 大, 但在 64 位 架构 下, 单个 进程 的 虚拟内存 确实 可以 申请 超过 4G , 比如 几十 G , 甚至 上百 G 应该 也可能 。
总的来说, 页 的 数量 很多, 如果 要 用 硬件 的 存储管理部件 来 保存 页表 的 话, 需要 很大 的 存储空间, 这个 可能 不现实 。
但 反过来 再想一下, 如果 有 1M 个页 , 也就是 100 万 个 页, 够用了吧 ? 假设 一个 页 的 大小 是 4 KB, 1M 个 页 的 空间是 1M * 4 KB = 4 GB ,
如果 10 M 个 页, 空间 是 40 GB, 100 M 个 页 , 空间 是 400 GB, 如果 把 页 弄大 一点, 比如 16 KB, 那么 100 M 个 页 的 空间 是 1.6 TB 。
把 100 M 个 存储单元 做到 硬件 里 , 按现在 的 技术来说, 好像 很平常 。 当然 这里 的 存储单元 比 一个 Byte 大, 应该是 一个 页表项 的 大小, 当然, 每个 页表项 可能 会 有 相应 的 一些 逻辑电路 用于 查找 页表项 和 判断 内存访问 是否 越界 。
但 因为 查找页表项 和 判断 内存访问 越界 的 逻辑电路 可能 是 每个页表项 都 会 有, 一个 页表项 对应 一个 页, 所以 当 页 的 数量 很大 时, 电路 体量 可能 很庞大 。
我 估计, 传统上, 到 目前为止, 页文件页表 的 管理 可能 是 由 软件 的 方式 实现 的, 即 由 操作系统 实现, 而不是 硬件 的 存储管理部件 。
在 内存 划出 一段 空间, 将 页表项 保存在 这段 内存 里 , 保存不下 的, 存入 页文件, 要用 的 时候, 再从 页文件 加载 到 内存, 这样, 只要 页文件 够大, 页文件页表 可以 持续 扩展 。
而 实际上, 保存不下 的 页表项 存入 页文件, 要用 的 时候, 再从 页文件 加载 到 内存, 这个 和 虚拟内存 类似, 可以 同样 用 虚拟内存 来 管理, 这是 “自己 管理 自己” 。
既然 统一 纳入 虚拟内存 管理, 那么 “在 内存 划出 一段 空间, 将 页表项 保存在 这段 内存 里” , 保存 页表项 的 这段 内存空间 也可以 不是 固定 的 , 统一 由 虚拟内存 管理 就好 。
总之, 这是 “自己 管理 自己” 。 这样 的 程序 是 可以 设计 出来 的 。
其实, 这跟 内存堆 的 管理 类似, 甚至 一样 。 这个 管理逻辑 是 很啰嗦 很麻烦 的 。
刚才 说远了 。
把 存储管理部件 搞清楚了, CPU 架构 也差不多 清楚了 。
把 逻辑电路 原理 搞清楚了, 复杂指令集 (CISC) 、微指令 、“流水” 架构 什么 的 , 也 都是 浮云 。
无非 就是 在 一个 时钟周期 尽量 执行 多个 逻辑运算 , 对于 需要 多个 时钟周期 才能 完成 的 指令功能, 协调安排 好 各个 逻辑运算, 使之 尽量 并行协作, 在 尽可能少 的 时钟周期 里 完成 指令功能 。
在 一个 时钟周期 里 尽量 执行 多个 逻辑运算, 这需要 固化 这些 逻辑运算 和 调度 这些 逻辑运算 的 逻辑运算 到 电路 里 , 电路 会 膨胀, 但 执行速度 会 变快 。
所以, 把 这些 搞清楚了, 画出 CPU 的 架构图 和 逻辑电路图 也很简单 。
但是, 当 电路 的 规模 很大 时, 要 计算出 电路参数 使得 电路 稳定运行, 这 并不简单, 需要 一些 工夫 。
当 电路 规模 很大 时, 在 硬件工艺 上, 要 把 电路 集成 到 很小 的 一块 硅片 上, 这 也不简单, 也需要 工夫 。
CPU 本身 也是 一个 计算机系统, 只不过 集成电路 和 “纳米工艺” 让 它 微观化 了, 而 我们 又 习惯于 用 高级 的 抽象 来 使用 计算机, 高级 的 抽象 比如 操作系统 、编程语言 、软件 , 所以, CPU 也 变得 复杂神秘深奥 起来 了 。
其实 本文 说 的 这些, 大部分 都是 我 猜 的 , 或者说 推测 的 。
但 不管 怎么说, 把 存储管理部件 搞清楚了, CPU 架构 也差不多 清楚了 。
所以呢, 设计 一个 CPU 的 存储管理部件, 这个 题 留给 大家 思考 吧, 哈哈 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2019-12-27 二元隐函数 数值求解