Rex_Zhang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

(一)一些概念:

分页:将物理内存分成固定大小的块,按照页来进行分配和释放;一般带下为4K(2^12)个字节;

大页:比如大小为2M(2^20)和2G(2^32)字节大小的页;

虚拟地址:软件编码通过虚拟地址来访问内存;由处理器将虚拟地址转换成物理地址;(虚拟地址对应虚拟内存,虚拟内存对应了numa系统的node节点)

页表:形成页目录表、页表、内容页的层级结构(为什么要三层结构?)用于虚拟地址到物理地址的转换;以虚拟地址2^32举例:

 

(二)TLB

在分层寻址的基础上,又引入了TLB的概念;TLB可以理解为一个缓存在cache中维护着前20位[31:12]对应关系的表项;如果能在TLB中匹配到逻辑地址,就能迅速通过页表项和[11:0]得到物理地址;反之,无法匹配则为不命中;

既然这样,如果TLB足够大,所有表项都缓存在cache中,保证每次命中,则转换过程可以非常快;而实际上TLB表项很小(受限于cache本身的大小?);

(三)大页

这时候大页的优势就体现出来了;通过配置大页,需要的TLB表项就很小;如果是以2M作为分页,只需要一个表项就可保证全部命中了~

(四)如何配置大页

操作环境的NUMA拓扑结构:

可以看到,一共有2个socket(CPU插槽-物理概念),每个socket有2个node,每个node有24个core,每个core单线程,共有96个threads。

大页分配可以通过linux启动参数设置或者启动后动态预留。

假设需要在node0上分配1024个2M大页,在linux中可以通过动态预留:

echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

dpdk中在node0节点出输入1024即可:

./home/z00383571/Dpdk_18.05/dpdk-stable-18.05.1/usertools/dpdk-setup.sh

而对于1G大小的页,必须通过设置启动参数的方式预留,不支持动态修改:

EulerOS:~ # cat /proc/cmdline
BOOT_IMAGE=hugepagesz=1G default_hugepagesz=1G hugepages=4 

(四)dpdk的大页使用

eal_hugepage_info_init() : //获取大页配置
eal_hugepage_info_read(); //根据配置初始化并映射内存  更具体的代码分析后续单独记录

 

使用大页需要mount到某个路径,比如:

#mkdir /mnt/huge
#mount -t hugetlbfs nodev /mnt/huge

可以修改/etc/fstab来避免每次开机重新设置

nodev /mnt/huge hugetlbfs defaults 0 0

对于1GB大小的大页。需要使用如下:

nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0

 

提问1:为什么需要分成三层的结构去进行查找?(如果改成两层,可以减少一次内存访问)

答:依旧以2^32虚拟地址为例,为了管理4K内存页,需要2^20个表项,因此需要建立一个4M的页表,即1024个物理页,内存代价过大。

提问2:假设pci网卡设备挂在cpu1的pcie总线上,大页申请在cpu0的node0上,会不会导致转发性能低?

答:跨socket使用内存,必然会导致性能降低;

posted on 2018-11-27 20:13  Rex_Zhang  阅读(2450)  评论(0编辑  收藏  举报