虚拟存储
虚拟存储
为什么电脑开这么多程序还能跑起来?
为什么同一个程序、同一个地址可以启动很多份?
虚拟存储
电脑的内存就是连续编址的“大数组”
那,在同一块地址,一个进程要写A,一个要写B,为什么两个进程“打架”的事情没有发生?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <unistd.h> // fork, getpid, sleep
#include <sys/mman.h> // mmap
#include <assert.h> // assert
#include <stdio.h> // printf
int main()
{
for (int i = 0; i < 3; i++)
{
fork(); // create some processes
}
volatile int *ptr = mmap(
(void *)0x20000000, // mapping address (hint)
1 << 20, // mapping size (1 MiB)
PROT_WRITE | PROT_READ, // read/write mapping
MAP_PRIVATE | MAP_ANONYMOUS, // mapping flags
-1, // file descriptor
0 // offset
);
assert((intptr_t)ptr != -1);
*ptr = getpid();
printf("#%d sets %p = %d\n", getpid(), ptr, getpid());
sleep(1);
printf("#%d *%p = %d\n", getpid(), ptr, *ptr);
}
fork():已经有一个进程,再去copy完全一模一样的内存
硬件实现
“我们要建立220到220的映射。“
radix tree 基数树
根据特定位比特的0/1情况,去定位某个特定的数的位置
存储器体系结构
第一层:寄存器
很多 ISA(比如 x86-64、RISC-V、ARM)寄存器数量远小于 256 个,但仍然用 8 bit(甚至更多) 来编码寄存器号。 为什么不只用需要的位数?例如 16 个寄存器只需要 4 bit。
我们执行的指令(如 mov $1, %rax)实际上 不会直接写物理寄存器 RAX, 而是会先被 重命名(Register Renaming) → 分配一个 物理寄存器(PRF: Physical Register File)地址 → 用于乱序执行、投机执行、异常恢复等。
如果只有 16 个寄存器,指令之间会“互相抢寄存器”,产生很多假依赖,例如:
1
2
3
mov $1, %rax
add %rbx, %rax
mov $2, %rax
后两条写了同一个 %rax,即使它们逻辑上互不相关,也会被阻塞。
架构寄存器只是一个逻辑名字,真正的值都存放在大量物理寄存器中。
第1.5层:MMU
第二层:缓存
1
2
3
volatile int *p = ……;
for (int i = 1; i < 1000; i++)
*p = 1;
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided
第三层:内存(DRAM)
内存 DRAM 即一个大数组 (三维数据结构)
new:NVRAM
第四层:外部存储器
- SSD Flash;磁盘
- 更大的延迟
- 更大的容量
- 更低的成本
This post is licensed under CC BY 4.0 by the author.







