use*_*112 16 c++ linux optimization performance memory-management
我在Linux上有一个C++应用程序,它对延迟非常敏感.我的内存使用量约为2GB,因此有4kb页面和64个TLB条目,我将遇到TLB未命中.
我在英特尔开发人员手册中读到2MB(或4MB?)"巨大"页面只能将TLB条目的数量减少一半,因此内存范围的增加抵消了TLB条目的减少,并且性能会更好.
如何在C++应用程序中使用"巨大"页面分配内存?我应该注意哪些权衡取舍?
我的Linux是Red Hat发行版.
我假设您只需要使用C++编写的特定应用程序的大页面,否则您只需更改系统的页面大小.以下方法适用于以任何语言编写的应用程序.
为了在特定应用程序中使用大页面,您需要构建内核以支持大页面支持.你必须用CONFIG_HUGETLBFS
选项构建内核
通过指定指定页面大小
hugepagesz=<size>
Run Code Online (Sandbox Code Playgroud)
在启动命令行上
要了解如何设置启动参数:http://www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html
设置大页面的使用
# echo 20 > /proc/sys/vm/nr_hugepages
Run Code Online (Sandbox Code Playgroud)检查大页面(可用,总计......)
# cat /proc/meminfo
Run Code Online (Sandbox Code Playgroud)当以上所有都正常时,现在你必须使用"如何将这些页面用于特定应用程序":类型hugetlbfs
为mount的文件系统
# mount -t hugetlbfs -o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,min_size=<value>,nr_inodes=<value> none /mnt/huge
Run Code Online (Sandbox Code Playgroud)
放置在此安装你的应用/mnt/huge
热潮,现在您的应用程序将使用页面大小由你定!
有关更多详细信息,请访问https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
大页面的优点/缺点:
优点:由于TLB未命中减少,页面错误减少,页面大小减少以及翻译减少而导致效率降低
缺点:更多的内部碎片:内存丢失,交换延迟更多(HUGETLBFS
页面不会刷出他们的映射是永久性的)更多细节检查https://lwn.net/Articles/359158/
编辑 还有API可用于分配大页面plz检查也许它有帮助
https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO
https://lwn.net/Articles/375096/
内核中的"hugetlb"文档应该对此有所帮助.
用户可以通过使用mmap系统调用或标准SYSV共享内存系统调用(shmget,shmat)来使用Linux内核中的大页面支持.
和:
例子
1)map_hugetlb:参见tools/testing/selftests/vm/map_hugetlb.c
2)hugepage-shm:参见tools/testing/selftests/vm/hugepage-shm.c
3)hugepage-mmap:参见tools/testing/selftests/vm/hugepage-mmap.c
4)libhugetlbfs(https://github.com/libhugetlbfs/libhugetlbfs)库提供了广泛的用户空间工具,以帮助实现大页面>可用性,环境设置和控制.
(这些路径指的是linux源代码树).
所以它基本归结为:
mmap
与MAP_HUGETLB
旗帜一起使用您还可以尝试使用透明的大页面支持,这在过去几年中的任何内核上都可用(至少在3.x和4.x范围内的任何版本以及各种2.6.x内核)。
主要的好处是您不需要设置任何特殊的“ hugetlbfs”,它“很有效”。缺点是可以保证:如果满足某些条件并且可以使用某些条件,则内核可能会以庞大的页面满足您的分配要求。与之不同的是,透明的大页面在启动时会保留一定数量的大页面,而这些大页面只能通过特定的调用才能访问,透明大页面会将大页面切入常规内存池。这需要连续的2MB物理内存块,由于物理内存碎片,随着时间的流逝,该块可能变得越来越少。hugetlbfs
此外,有多种内核可调参数会影响您是否获得巨大的页,其中最重要的是/sys/kernel/mm/transparent_hugepage/enabled
。
最好的选择是在2MB的边界上分配块posix_memalign
,然后madvise(MADV_HUGEPAGE)
在分配的区域上进行一次首次接触之前。它还适用于类似的变体aligned_alloc
。以我的经验,在/sys/kernel/mm/transparent_hugepage/enabled
设置了always
此功能的系统上通常会产生巨大的页面。但是,我主要在具有大量可用内存且运行时间不太长的系统上使用。
如果您使用2GB的内存,则可能会受益于巨大的页面。如果您以小块的形式分配所有malloc
内存,例如,通过透明分配的大页很有可能不会启动,那么无论使用了多少内存,您都可以考虑以THP感知的方式进行分配(通常是单个内存对象类型)。
我还写了一个库来确定您是否从任何给定的分配中真正获得了巨大的页面。这在生产应用程序中可能没有用,但是如果您尝试使用THP的方法,这可能是有用的诊断,因为至少可以确定是否获得了THP。