Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >[linux][memory]hugetlb和hugepage技术分析

[linux][memory]hugetlb和hugepage技术分析

作者头像
皮振伟
发布于 2018-04-09 03:17:36
发布于 2018-04-09 03:17:36
8.2K0
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏

前言: 乍一看,hugetlb和hugepage还挺像的,好像都是所谓的“大页”。然而,却很难说出来它们的差异。作者也是花了写时间翻翻代码,写了几个测试的例子,加上用工具据实测了几个关键参数,才明白。 分析: 1,page fault 用户大多数情况下申请内存的方法: a,使用malloc函数族,其实是glibc封装了brk/mmap。这种情况下分配的是虚拟内存,并没有直接分配物理内存。 b,调用brk分配,这种情况很少见,并只分配虚拟内存。 c,使用mmap,分配出来虚拟内存。如果flags带有MAP_POPULATE,则直接分配物理内存,否则不分配物理内存。 d,使用mlock,则mlock指定的地址空间内,要分配物理内存。 上述的几种情况中,其实大多数情况下,都是只分配虚拟内存,并不分配物理内存。 对于这种情况,在CPU访问到没有分配物理内存的地址的时候,MMU会产生exception(这个exception就是page fault),kernel处理page fault,如果访问的地址合法,权限合法,则分配相应的物理内存。 2,2M page size 例如进程分配了4G的虚拟内存,那么,就会产生4G / 4K = 1M次page fault。 如果page size变大呢?page size为2M的情况下,会产生4G / 2M = 2K次page fault。 相比之下,减少了很多次page fault。换言之,就是节省了好多计算量,节省了处理page fault的CPU资源。 这里还有一个问题,为什么是2M,而不是其他呢?原因是在x86上,一个pmd能管理的内存是2M。 3,hugetlb shell中敲cat /proc/meminfo | grep -i HugePage:

可以看到,Hugepace的大小事2048K,即2M。当前没有HugePages的total,free等。 执行:echo 1024 > /proc/sys/vm/nr_hugepages

通过修改/proc/sys/vm/nr_hugepages,来控制kernel中的HugePages的数量。 在执行mmap函数中,flags带着MAP_HUGETLB则分配2M的page。 这里需要注意的是,HugePages不在buddy system中继续管理了,在修改echo 1024 > /proc/sys/vm/nr_hugepages的前后对比,也会发现,系统中的free memory减少了2G。 那么问题来了,如果buddy system中没有那么多连续的2M会怎么样呢?会分配出问题。所以需要在开机的时候,就分配大量的2M page。最差情况就是,2M page有很多剩余,而操作系统的free memory很少。 hugetlb的主要逻辑代码在linux-4.0.4/mm/hugetlb.c中,VM_HUGETLB的宏定义数值是0x00400000。 再需要说明一点,hugetlb标记的vma,是不能做ksm/uksm的。 4,hugepage linux提供函数int madvise(void *addr, size_t length, int advice); 其中advice有MADV_HUGEPAGE。 先看madvise,其实就是advise类型的,并非强制的。设定了MADV_HUGEPAGE的地址空间,可以在smaps中查到hg标记。 敲命令cat /proc/PID/smaps可以看到:

查看当前系统的hugepage的策略:cat /sys/kernel/mm/transparent_hugepage/enabled:

一共三种,always,madvise,never。修改的话,也同样:echo “always” > /sys/kernel/mm/transparent_hugepage/enabled 关于hugepage的代码,主要在linux-4.0.4/mm/huge_memory.c中实现。大意是,如果是hugepage的vma发生了page fault,则尽量使用2M的page来分配,如果分配失败,则使用普通的page(4K)来分配。同时,还有一个后台内核线程khugepaged,周期性扫描vma,如果kernel中有了2M的page,会尽量 使用2M page替换4K page。M_HUGEPAGE的宏定义是0x20000000。可见,和HUGETLB还是不同的。另外,hugepage是可以做ksm的。 5,test 作者写了一段简单的代码: #include <sys/mman.h> #include <sys/time.h> #include <stdio.h> #include <string.h> #define SIZE ((size_t)1024*1024*1024*1) int main(int argc, char *argv[]) { void *p = NULL; struct timeval starttv, endtv; int ret = 0; size_t index = 0; p = mmap(NULL, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (p == MAP_FAILED) { perror("mmap"); return 0; } if (argc == 2) { printf("madvise\n"); ret = madvise(p, SIZE, MADV_HUGEPAGE); if (ret < 0) { perror("madvise"); return 0; } } getchar(); ret = gettimeofday(&starttv, NULL); if (ret < 0) { perror("gettimeofday starttv"); return 0; } for (index = 0; index < SIZE; index += 4096) *((int*)(p + index)) = 0xc5; ret = gettimeofday(&endtv, NULL); if (ret < 0) { perror("gettimeofday starttv"); return 0; } printf("time cost : %ld\n", (endtv.tv_sec - starttv.tv_sec) * 1000000 + endtv.tv_usec - starttv.tv_usec); getchar(); return 0; } 先不要在意没有执行munmap的那段~: 编译:gcc hugepace.c -o hugepage 执行:a,./hugepage看执行时间 b, ./hugepage huge看执行时间

实验结果上来看,确实减少了执行时间。 6,perf 上面看到了执行时间的变少,再来看看具体的原因。 perf是性能分析的首选。 启动上述的测试程序hugepage,会停留在第一个getchar()位置上,这时候,敲:perf record -e page-faults -p PID;等到函数执行完,会在perf的shell里面生成perf.data文件;敲:perf report: 两次的结果分别是:

可见,page-faults的差别还是有很大差别。 7,/sys/kernel/mm/transparent_hugepage/enabled 前文提到过,这个参数有三个,当使用always的时候,其实kernel不在乎是否vma带有了VM_HUGEPAGE选项,都会优先使用2M page的。这里需要注意一下。 后记: 关于hugepage和hugetlb的代码,这里没有仔细分析,原因是代码比较繁杂,作者也只是大概看了逻辑,没完全看透。 从使用的角度来说,作者并不欣赏hugetlb,首先会划出去很多内存,让内存管理复杂化,诚然会让大块连续内存分配的情况下性能有所提高,不过看实验结果也没那么明显,还要牺牲挺多高级特性。而hugepage则好很多,非强制,hugepage使用的内存也是在buddy system的管理框架内。 网上有人说使用hugetlb会加速CPU访问内存的速度,作者并不清楚,也没想到一个好的办法来实验。期待有朋友给出来好办法或者数据。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HugePages(大内存页)实现完全解析
在《一文读懂 HugePages的原理》一文中介绍了 HugePages(大内存页)的原理和使用,现在我们来分析一下 Linux 内核是怎么实现 HugePages 分配的。
用户7686797
2021/05/11
3.1K0
HugePages(大内存页)实现完全解析
​Linux内核透明巨型页支持
处理大内存的性能关键计算应用程序工作集已经运行在libhugetlbfs之上,然后依次运行 hugetlbfs。透明的巨型页面支持是另一种使用大页为虚拟内存提供大页支持的方法, 该支持自动提升和降低页面大小和没有hugetlbfs的缺点。
用户7244416
2022/08/31
2.9K0
从内核世界透视 mmap 内存映射的本质(原理篇)
之前有不少读者给笔者留言,希望笔者写一篇文章介绍下 mmap 内存映射相关的知识体系,之所以迟迟没有动笔,是因为 mmap 这个系统调用看上去简单,实际上并不简单,可以说是非常复杂的一个系统调用。
bin的技术小屋
2023/10/30
5.2K4
从内核世界透视 mmap 内存映射的本质(原理篇)
宋宝华:论Linux的页迁移(Page Migration)完整版
对于用户空间的应用程序,我们通常根本不关心page的物理存放位置,因为我们用的是虚拟地址。所以,只要虚拟地址不变,哪怕这个页在物理上从DDR的这里飞到DDR的那里,用户都基本不感知。那么,为什么要写一篇论述页迁移的文章呢?
Linux阅码场
2020/08/18
4.8K0
宋宝华:论Linux的页迁移(Page Migration)完整版
宋宝华:论Linux的页迁移(Page Migration)上集
对于用户空间的应用程序,我们通常根本不关心page的物理存放位置,因为我们用的是虚拟地址。所以,只要虚拟地址不变,哪怕这个页在物理上从DDR的这里飞到DDR的那里,用户都基本不感知。那么,为什么要写一篇论述页迁移的文章呢?
Linux阅码场
2020/07/30
1.7K0
宋宝华:论Linux的页迁移(Page Migration)上集
技术分享 | 浅谈一下大页
Linux下的大页分为两种类型:标准大页(Huge Pages)和透明大页(Transparent Huge Pages)。
爱可生开源社区
2023/02/13
1.2K0
五万字 | 深入理解Linux内存管理
作者简介: 程磊,一线码农,在某手机公司担任系统开发工程师,日常喜欢研究内核基本原理。 1.1 内存管理的意义 1.2 原始内存管理 1.3 分段内存管理 1.4 分页内存管理 1.5 内存管理的目标 1.6 Linux内存管理体系 2.1 物理内存节点 2.2 物理内存区域 2.3 物理内存页面 2.4 物理内存模型 2.5 三级区划关系 3.1 Buddy System 3.1.1 伙伴系统的内存来源 3.1.2 伙伴系统的管理数据结构 3.1.3 伙伴系统的算法逻辑 3.1.4 伙伴系统的接口 3.1
刘盼
2022/08/26
4K0
五万字 | 深入理解Linux内存管理
Linux 透明大页 THP 和标准大页 HP
在 Linux 中大页分为两种: Huge pages (标准大页) 和 Transparent Huge pages(透明大页)。
JiekeXu之路
2022/05/17
3.3K0
Linux 透明大页 THP 和标准大页 HP
Linux|大内存页(HugePage)的三三两两
最近有同事问了几个关于大内存页(HugePage)的问题,就顺便复习并拓展的看了下相关的内容,根据自己的理解做个简单总结,如有纰漏欢迎指正。
琉璃康康
2022/04/19
3.7K0
Linux|大内存页(HugePage)的三三两两
Linux 标准大页和透明大页
Huge pages ( 标准大页 ) 和 Transparent Huge pages( 透明大页 )
用户1278550
2021/07/16
5.9K0
一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults
在前面两篇介绍 mmap 的文章中,笔者分别从原理角度以及源码实现角度带着大家深入到内核世界深度揭秘了 mmap 内存映射的本质。从整个 mmap 映射的过程可以看出,内核只是在进程的虚拟地址空间中寻找出一段空闲的虚拟内存区域 vma 然后分配给本次映射而已。
bin的技术小屋
2023/12/21
3.9K0
一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults
从 Linux 内核角度探秘 JDK MappedByteBuffer
在之前的文章《一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现》 中,笔者为大家详细剖析了 JDK Buffer 的整个设计体系,从总体上来讲,JDK NIO 为每一种 Java 基本类型定义了对应的 Buffer 类(boolean 类型除外)。
bin的技术小屋
2024/03/25
2830
从 Linux 内核角度探秘 JDK MappedByteBuffer
bihash默认使用main-heap内存
前段时间在vpp交流群讨论bihash在默认条件下初始化的时候使用的是系统内存,还是大页内存。讨论也修正我的知识库,对bihash的理解也还停留在20.09版本之前。
dpdk-vpp源码解读
2023/03/07
9471
bihash默认使用main-heap内存
Linux HugePage 特性
    HugePage,就是指的大页内存管理方式。与传统的4kb的普通页管理方式相比,HugePage为管理大内存(8GB以上)更为高效。本文描述了什么是HugePage,以及HugePage的一些特性。
Leshami
2018/08/14
1.2K0
Linux HugePage 特性
THP
使用huge page,可以在TLB容量固定的情况下,提高TLB的命中率,即便TLB miss,因为减少了页表级数,也可以减少查找页表的时间。在内存虚拟化中,由于地址转换需要的级数更多,huge page能发挥的作用就显得更为重要。
233333
2022/12/02
5680
THP
深入理解Linux内核之HVO(HugeTLB Vmemmap Optimization)
本文主要介绍内存管理中的HVO(HugeTLB Vmemmap Optimization)特性,通过HVO可以节省管理HugeTLB 页面元数据(struct page)的内存占用,甚至在缓存的空间局部性表现上也更好。本文通过图解结合源代码分析的方式让大家彻底理解HVO的实现原理,且本文主要以2M大小的HugeTLB 页面为例讲解。
用户7244416
2024/06/13
4140
深入理解Linux内核之HVO(HugeTLB Vmemmap Optimization)
YashanDB 安装前操作系统参数调整
当 YashanDB 安装在 Linux 环境中时,为使系统达到更好的性能,建议进行下述配置调整。
用户10349277
2025/03/06
540
Linux:/proc/meminfo参数详细解释
/proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 ,/proc/meminfo所包含的信息比”free”等命令要丰富得多,然而真正理解它并不容易,比如我们知道”Cached”统计的是文件缓存页,manpage上说是“In-memory cache for files read from the disk (the page cache)”,那为什么它不等于[Active(file)+Inactive(file)]?AnonHugePages与AnonPages、HugePages_Total有什么联系和区别?很多细节在手册中并没有讲清楚,本文对此做了一点探究。
233333
2023/07/24
1.7K0
Linux:/proc/meminfo参数详细解释
从内核世界透视 mmap 内存映射的本质(源码实现篇)
本文我们将进入到内核源码实现中,来看一下虚拟内存分配的过程,在这个过程中,我们还可以亲眼看到前面介绍的 mmap 内存映射原理在内核中具体是如何实现的,下面我们就从 mmap 系统调用的入口处来开始本文的内容:
bin的技术小屋
2023/10/30
7270
从内核世界透视 mmap 内存映射的本质(源码实现篇)
一文读懂 HugePages(大内存页)的原理
在介绍 HugePages 之前,我们先来回顾一下 Linux 下 虚拟内存 与 物理内存 之间的关系。
用户7686797
2021/04/23
6.8K0
一文读懂 HugePages(大内存页)的原理
相关推荐
HugePages(大内存页)实现完全解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档