大数跨境
0
0

内存基础知识(十八)-- 虚拟地址/物理地址/内存地址, 有何不同

内存基础知识(十八)-- 虚拟地址/物理地址/内存地址, 有何不同 IT知识刺客
2025-11-18
6
导读:从第17篇开始,我们又开启了一个新的话题:编址。为了后续描述方便,关于地址,有三个名词要明确下,它们是:虚拟地址:软件层程序使用的地址。物理地址:CPU中使用的地址。内存地址:真正的内存条中数据的地址
这是内存基础知识系列的第18篇,你可以到 基础软件开发 这里,找到前17篇。
从第17篇开始,我们又开启了一个新的话题:编址。为了后续描述方便,关于地址,有三个名词要明确下,它们是:
  • 虚拟地址:软件层程序使用的地址。
  • 物理地址:CPU中使用的地址。
  • 内存地址:真正的内存条中数据的地址。
虚拟地址没什么好说的,我们软件层(包括操作系统内核)都使用的是它。
通常来说,程序是没有办法绕过虚拟地址,直接以物理地址访问内存的。
在CPU刚刚上电的最初始阶段,MMU还没有开始工作,这个时候CPU会以物理地址方式进行少量的的内存访问。
当CPU完全的起动之后,程序层无法绕开MMU和虚拟地址、直接以物理地址使用内存。
注:我主要针对x86-64和服务器ARM。小型个人嵌入式设备不在我的讨论范围内
Linux内核提供 ioremap() 函数,可以先将一个物理地址映射到某个虚拟地址,然后再使用虚拟地址访问内存,还是绕不开虚拟地址。
简而言之,虚拟地址必不可少。
CPU使用 MMU 将虚拟地址翻译为物理地址。在CPU内,就要使用到物理地址了。
比如L1 Cache通常使用VIPT (Virtual Index Physical Tag)方式检索。即,L1 Cache的索引用虚拟地址,但标签(Tag)使用物理地址对比。
而L2/L3 Cache,则使用PIPT (Physical Index Physical Tag)方式检索,索引和标签,全部都是物理地址。

在内存系列完结后,我计划开启Cache系列。因此VIPT、PIPT啥的,到Cache系列再细聊吧。本篇先简单提一下,CPU使用物理地址检索Cache。因此,CPU内会使用物理地址(也会使用虚拟地址,因为L1 Cache是VIPT)。

最后一个内存地址,这是一个数据在内存中真正的地址。

如果指令是访存访存指令,常见的如load/store,Core会把物理地址发送给MC(内存控制器)。MC会把物理地址按编址规则解析为内存地址,然后再和内存交互,读写数据。

内存地址大概长这个样子:

通道号:RANK号:BG号:Bank号:行号:列号

更准确的说法,应该是“内存地址中包含以上信息”。这里的内存通道、RANK、BG、Bank和Memory Array中的行、列,这些概念我们在前17篇中,反复提到了,这里不再赘述。

我当时看到这样的内存地址时,第一时间就觉得,这好像我们的住址一样啊,某城市、某区/县、某街道、某小区、几号楼、几单元、几号。

我之所以详细讲这一块,主要是地址和性能关系是很密切的。比如,一名快递小哥要送快递,最快的方式,就是把1号楼所有快递全送到,再去送2号楼的。

较慢的方式就是跑1号楼送一件快递,再跑2号楼送一件,再去1号楼送一件,……。

这是常识。

我们在访问内存时也一样。只不过,我们要根据编址规则,合理的排列我们的数据,才能让快递员(CPU或MC)以最快方式访问内存,以提升吞吐、缩短延迟。

具体要怎么做呢?

先得破译出来“编址规则”,即,“物理地址是按照什么样的规律转换为内存地址”。

但编址规则是CPU/GPU各类芯片厂商的商业秘密,通常不轻易示人。

好在破译它也并非不可能,接下来几篇我们就要聚焦这个问题,破译下CPU中内存控制器的编址规则。然后根据编址规则,看看如何排列我们的数据,才能进一步压榨出CPU与内存的潜力。

在破译编址规则之前,还要回到前面“流量”观测的话题,因为通过“观测流量”破译编址规则,是最简单的方式。

从第11到第15篇,我用5篇文章详细描述了如何在RANK层观察内存流量:

内存基础知识(十一)-- 查询内存通道编号
内存基础知识(十二)-- 如何得到精确的流量数据
内存基础知识(十三)-- 在RANK层精细统计内存流量
内存基础知识(十四)-- 让内存条中的“页”现出原形
内存基础知识(十五)-- 使用perf分析内存流量瓶颈

后续,我们要更进一步,在BG层、Bank层计算流量。

在内存系列11~15中,我提供了两种方式统计流量:

  • 使用perf_event_open()系统调用,自行开发监控程序
  • 使用 perf 工具

perf_event_open()是 perf 工具的基础,使用它可以得到更精确的流量,但如果对 perf工具 原理并不是特别感兴趣,直接使用perf能更快上手。

后续,我将尽量使用 perf 工具,力求让大伙都可以用最简单的方式,上手研究内存原理,复现和我类似的测试结果。


最后附上内存系列前17篇,包括NUMA系列(NUMA的基础知识马上就要用到了);

不能说的秘密--内存竟然有隐藏带宽
内存基础知识(二)
内存基础知识(三)-- BANK
DDR5核心频率只有200MHz(兆赫兹):真的假的
内存基础知识(五)-- BankGroup前传
内存基础知识(六)-- BankGroup登场
内存基础知识(七)-- BankGroup正传
内存基础知识(八)-- 如何统计内存流量
内存基础知识(九)-- 内存通道(Channel)详解
内存基础知识(十)-- 内存控制器是怎么完成读操作的
内存基础知识(十一)-- 查询内存通道编号
内存基础知识(十二)-- 如何得到精确的流量数据
内存基础知识(十三)-- 在RANK层精细统计内存流量
内存基础知识(十四)-- 让内存条中的“页”现出原形

内存基础知识(十五)-- 使用perf分析内存流量瓶颈

内存基础知识(十六)-- Rank/Chip/BG/Bank,软硬结合彻底搞懂内存底层结构

内存基础知识(十七)-- 什么是内存地址

另外,我之前还写过一个 NUMA 系列,NUMA相关的基础知识,马上也要用到了:

NUMA的逆行人生:一文讲清什么是NUMA

NUMA的逆行人生:一文讲清什么是NUMA(第二弹)

NUMA的逆行人生:一文讲清什么是NUMA(第三弹)

NUMA的逆行人生:一文讲清什么是NUMA(第四弹)

NUMA的逆行人生:一文讲清什么是NUMA(第五弹)

NUMA的逆行人生:一文讲清什么是NUMA(大结局)

还有这个系列,讲CPU执行阶段流水线的,虽然和内存没有直接关系,但个人感觉相当不错,值得阅读:

跟着苍老师学体系结构:深入突破基础软件开发(一)

深入突破基础软件开发(二)

深入突破基础软件开发(三)

深入突破基础软件开发(大结局)

【声明】内容源于网络
0
0
IT知识刺客
基础软件开发 HPC(高性能计算) HPC数据库研发 数据库内核 向量计算 计算机体系结构 数据库 DBA CPU原理
内容 83
粉丝 0
IT知识刺客 基础软件开发 HPC(高性能计算) HPC数据库研发 数据库内核 向量计算 计算机体系结构 数据库 DBA CPU原理
总阅读26
粉丝0
内容83