N)UMA 模型中的内存组织------《深入Linux内核架构》笔记

http://blog.csdn.net/daniel_ice/article/details/6833835


UMA(一致内存访问,uniformmemory access): 计算将内存以连续的方式组织起来。SMP中每个cpu访问各内存区具有一样的速度

NUMA(非一致内存访问,non-uniformmemory access):SMP中的各个cpu都有本地的内存,可支持快速访问。各个cpu之间通过总线连接,对其它cpu的内存的访问将会慢于对自己内存的访问。结构如下图:

在内核中内存划分为节点,每个节点关联到一个cpu,在内核中用pg_data_t表示。


各个节点进一步划分为域,在内核中用structzone来表示。对于x86来说,总共有ZONE_DMA,ZONE_NORMAL,ZONE_HIGMENT三个域实例。ZONE_DMA负责对负责分配用于DMA操作的内存,ZONE_NORMAL负责分配可以直接映射到内核段的内存,ZONE_HIGMENT负责分配超出内核段的物理内存(应该是指另外的3GB内存)

注意:内存域这个概念是对于物理内存而言的,而不是虚拟内存


每个域中会包含一个structfree_area成员,该成员用于实现伙伴系统,管理该区域中的空闲内存页。


页在内核中对应的结构体为structpage,该结构体采用union语法来减少结构体的大小。Page中的mapping指定了页帧所在的地址空间,virtual用于存储该页的虚拟地址,在x86体系中virtual成员是没有的。  


上图展示了节点,域,页之间的关系。这里再对每个概念所涉及功能进一步阐述(这里只是简单介绍部分功能,详细信息请参考《深入linux内核架构》3.2节):


  1. //节点(简化版)  
  2. typedef struct pglist_data {  
  3.     struct zone node_zones[MAX_NR_ZONES];//指明该节点下包含有多少个域  
  4.     //指向page实例数组的指针,用于描述节点的所有物理内存页,它包含了节点中所有内存域的页  
  5.     struct page *node_mem_map;  
  6.     //备用节点的内存域的链表,用于在NUMA中,该节点无法提供内存,需要到其它的节点分配  
  7.     struct zonelist node_zonelists[MAX_ZONELISTS];  
  8.     struct bootmem_data *bdata;//用于为分配在系统初始化之前所需要的内存?  
  9. }pg_data_t;  
  10.   
  11.   
  12. //域(简化版,并没有考虑NUMA)  
  13. struct zone {  
  14.     unsigned long watermark[NR_WMARK];//系统在分配页之后,需要保证剩余下了的页的数量大于水印  
  15.     //当空闲页数低于该值时,读取空闲页将会导致附加的操作被执行,而这一附加的操作是为了躲避能让水印被违反的per-cpucounter drift。  
  16.     unsigned long percpu_drift_mark;  
  17.     //分别为各个内存域指定若干的保留页,用于系统的紧急内存分配  
  18.     unsigned long lowmem_reserve[MAX_NR_ZONES];  
  19.     struct per_cpu_pageset pageset[NR_CPUS];//用于存放冷热页,在高速缓存中的页称为热页。  
  20.     struct free_area free_area[MAX_ORDER];//用于实现伙伴系统  
  21.     spinlock_t lock;//自旋锁  
  22.     ZONE_PADDING(_pad1_)//用于实现将每个自旋锁放置于不同的缓存行,x86中每个缓存行为32Bytes  
  23.     //以下两个成员用于页面回收程序使用  
  24.     spinlock_t lru_lock;  
  25.     struct zone_lru {  
  26.         struct list_head list;  
  27.     }lru[NR_LRU_LISTS];//分别保存活动页和非活动页。页访问频繁及认为为活动页  
  28.     struct zone_reclaim_stat reclaim_stat;  
  29.     unsigned long pages_scanned; /* since last reclaim */  
  30.     unsigned long flags;// 用于描述内存域所处的状态,比如被LOCKED,所有的不能回收  
  31.     atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];//用于保存对该域的统计数据,如活动页的数目  
  32.     ZONE_PADDING(_pad2_)  
  33.     //以下三个字段,实现进程等待某一页  
  34.     wait_queue_head_t *wait_table;  
  35.     unsigned long wait_table_hash_nr_entries;  
  36.     unsigned long wait_table_bits;  
  37.     struct pglist_data *zone_pgdat;//关联到自己所属的节点  
  38.     unsigned long zone_start_pfn;// 内存域的第一个页帧  
  39.     unsigned long spanned_pages; //总共的长度,包含空洞  
  40.     unsigned long present_pages; //内存数量(不包含空洞)  
  41.     const char *name;//域的名字,内核将很少使用的字段放到结构体的末尾  
  42. }____cacheline_internodealigned_in_smp;  
  43.   
  44.   
  45. //页(简化版),slab,freelist,inuse用于实现slub  
  46. struct page {  
  47. unsigned long flags ;//记录该页的状态信息,如该页是否被LOCKED,是否脏等等  
  48.     atomic_t_count;//使用计数,表示内核中引用该页的次数  
  49.     union {  
  50.         atomic_t_mapcount;// _mapcount为32位,表示在页表中多少项指向该页  
  51.         struct {  
  52.             u16inuse;//用于slub分配器,对象的数目,该成员不需要原子特性  
  53.             u16objects;  
  54.         };  
  55.     };  
  56.     union {  
  57.         struct {  
  58.             //一个指向私有数据的指针,根据页的用途,可以用不同的方式使用该指针  
  59.             unsigned longprivate;  
  60.             //指定页帧所在的地址空间,index是页帧在内部的偏移量。当mapping最低位置1时该指针并不指向address_space实例,而是指向anon_vma  
  61.             struct address_space *mapping;  
  62.         };  
  63.         struct kmem_cache *slab;//用于SLUB分配器,指向slab的指针  
  64.         struct page *first_page;//指向compoundpage中的首页  
  65.     };  
  66.     union {  
  67.         pgoff_tindex;/* Our offset within mapping. */  
  68.         void *freelist;/* SLUB: freelist req. slablock */  
  69.     };  
  70.     struct list_head lru;//用于将页按不同的类别分组,如活动和不活动  
  71. #ifdefined(WANT_PAGE_VIRTUAL)  
  72.     void*virtual;  
  73. //在x86体系中,没有该成员  
  74. #endif/*WANT_PAGE_VIRTUAL */ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值