1.请简述内存架构中UMA和NUMA的区别。
-
UMA架构:内存有统一的结构并且可以统一寻址。目前大部分嵌入式系统、手机系统以及台式机操作系统等采用UMA架构。如下图,该系统使用UMA架构,有4个CPU,它们都有L1高速缓存,其中CPU0和CPU1组成一个簇(Cluster0),它们共享一个L2高速缓存。另外,CPU2和CPU3组成另外一个簇(Cluster1),它们共享另外一个L2高速缓存。4个CPU都共享同一个L3的高速缓存。最重要的一点,它们可以通过系统总线来访问物理内存DDR。
-
NUMA架构:系统中有多个内存节点和多个CPU簇,CPU访问本地内存节点的速度最快,访问远端的内存节点的速度要慢一点。如下图,该系统使用NUMA架构,有两个内存节点,其中CPU0和CPU1组成一个节点(Node0),它们可以通过系统总线访问本地DDR物理内存,同理,CPU2和CPU3组成另外一个节点(Node1),它们也可以通过系统总线访问本地的DDR物理内存。如果两个节点通过超路径互连(Ulra Path Interconnect,UPI)总线连接,那么CPU0可以通过这个内部总线访问远端的内存节点的物理内存,但是访问速度要比访问本地物理内存慢很多。
2.CPU访问各级存储结构的速度是否一样?
- 一般来说,CPU访问各级内存的速度是不一样的。CPU访问各级内存设备的延时如下表:
访问类型 | 延迟 |
---|---|
L1高速缓存命中 | 约4个时钟周期 |
L2高速缓存命中 | 约10-个时钟周期 |
L3高速缓存命中 (高速缓存行没有共享) | 约40个时钟周期 |
L3高速缓存命中 (和其他CPU共享高速缓存行) | 约65个时钟周期 |
L3高速缓存命中 (高速缓存行被其他CPU修改过) | 约75个时钟周期 |
访问远端的L3高速缓存 | 约100~300个时钟周期 |
访问本地DDR物理内存 | 约60ns |
访问远端内存节点的DDR物理内存 | 约100ns |
3.请绘制内存管理常用的数据结构的关系图。如mm_struct、VMA、vaddr、page、 PEN、PTE、zone、paddr和pg_data等,并思考如下转换关系。
3.1 如何由mm_struct和vaddr找到对应的VMA?
3.2 如何由page 和VMA 找到 vaddr?
3.3 如何由page找到所有映射的VMA?
3.4 如何由VMA和vaddr找出相应的page数据结构?
3.5 page和PFN之间如何互换?
3.6 PFN和paddr之间如何互换?
3.7 page和PTE之间如何互换?
3.8 zone和page之间如何互换?
3.9 zone和pgdata之间如何互换?
4.在ARM64内核中,内核映像文件映射到内核空间的什么地方?
- 内核映像文件,映射到内核的线性映射区,并通过smp_cpus_done()->mark_liner_text_alias_ro()函数将该区域设为只读。
5.在ARM64内核中,内核空间和用户空间是如何划分的?
- ARM32内核系统中一个能使用的虚拟空间是4GB,用户空间和内核空间的划分通常按3:1来划分。
- ARM64内核系统中才用48位物理寻址机制,最多可以寻址256TB。用户空间:0x0000_0000_0000_0000 ~ 0x0000_FFFF_FFFF_FFFF。内核空间:0xFFFF_0000_0000_0000 ~ 0xFFFF_FFFF_FFFF_FFFF。
6.在系统启动时,ARM64 Linux内核如何知道系统有多大的物理内存?
- 可以通过观察启动时的log如:
[ 0.000000] On node 0 totalpages: 129920
[ 0.000000] Normal zone: 1024 pages used for memmap
[ 0.000000] Normal zone: 0 pages reserved
[ 0.000000] Normal zone: 129920 pages, LIFO batch:63
- 从log可以看出我们只有一个内存节点node 0,物理页面总数是129920,每个页面大小是4KB,因此总物理内存129920*4/1024=507.5MB。
7.物理内存页面如何添加到伙伴系统中,是一页一页添加,还是以2^n来添加呢?
- 伙伴系统按照内存块的大小(即2^n)来添加到不同链表中,其中能容纳单个内存块的最大值为2 ^ 10个物理页面,即1024(0x400)个物理页面。假设页帧号start起始地址为0x8800e,end=0xaecea。则__free_pages_memory将创建如下空间物理块:
__free_pages_memory:start=0x8800e, order=1, __ffs()=1, ffs()=2
__free_pages_memory:start=0x88010, order=4, __ffs()=4, ffs()=5
__free_pages_memory:start=0x88020, order=5, __ffs()=5, ffs()=6
__free_pages_memory:start=0x88040, order=6, __ffs()=6, ffs()=7
__free_pages_memory:start=0x88080, order=7, __ffs()=7, ffs()=8
__free_pages_memory:start=0x88100, order=8, __ffs()=8, ffs()=9
__free_pages_memory:start=0x88200, order=9, __ffs()=9, ffs()=10
__free_pages_memory:start=0x88400, order=10, __ffs()=10, ffs()=11
__free_pages_memory:start=0x88800, order=10, __ffs()=10, ffs()=11
__free_pages_memory:start=0x88400, order=10, __ffs()=10, ffs()=11
.......
__free_pages_memory:start=0xaec00, order=10, __ffs()=10, ffs()=11
__free_pages_memory:start=0xaec80, order=7, __ffs()=7, ffs()=8
__free_pages_memory:start=0xaecc0, order=6, __ffs()=6, ffs()=7
__free_pages_memory:start=0xaece0, order=5, __ffs()=5, ffs()=6
__free_pages_memory:start=0xaece8, order=3, __ffs()=3, ffs()=4
__free_pages_memory:start=0xaece9, order=1, __ffs()=1, ffs()=2
- order=0——>有0个4KB内存块。
- order=1——>有2个8KB内存块。
- order=2——>有0个16KB内存块。
- order=3——>有1个32KB内存块。
- order=4——>有1个64KB内存块。
- order=5——>有2个128KB内存块。
- order=6——>有2个256KB内存块。
- order=7——>有7个512KB内存块。
- order=8——>有1个1MB内存块。
- order=9——>有1个2MB内存块。
- order=10——>有154个4MB内存块。
版权声明:本文为weixin_39247141原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。