我在英特尔开发者手册中读到,2MB(或4MB?)的“巨大”页面只能将TLB条目数量减半,因此内存范围的增加抵消了TLB条目的减少,这样性能会更好。
如何在C++应用程序中分配使用“巨大”页面的内存?有什么需要注意的权衡取舍吗?
我的Linux是Red Hat发行版。
您还可以尝试使用透明巨页支持,它在过去几年的任何内核中都可用(至少在3.x和4.x范围以及各种2.6.x内核中)。
主要好处是您不需要设置任何特殊的“hugetlbfs”,它“只需运行”。缺点是不能保证:如果满足某些条件并且有一些可用,内核可能用巨大的页面满足您的分配。与在启动时保留一定数量的巨型页面的hugetlbfs不同,这些页面仅通过特定调用可用,透明巨型页面从一般内存池中划分出巨大的页面。这需要连续的2MB物理内存块,由于物理内存碎片化,随着系统保持时间变长,这些块可能变得罕见。
此外,有各种内核可调整项会影响您是否获得巨型页面,其中最重要的是/sys/kernel/mm/transparent_hugepage/enabled
。
最好的方法是使用posix_memalign
在2MB边界上分配块,然后在第一次触摸之前对分配区域执行madvise(MADV_HUGEPAGE)
。它也适用于类似aligned_alloc
的变体。根据我的经验,在将/sys/kernel/mm/transparent_hugepage/enabled
设置为always
的系统上,这通常会导致产生巨型页面。但是,我大多数情况下在具有相当空闲内存和不太长的正常运行时间的系统上使用。
如果您正在使用2GB内存,则可能从巨型页面中获得显着的好处。如果您通过malloc
分配所有小块,则透明巨页面不会启用的风险很高,因此您还可以考虑以THP-aware的方式分配使用大部分内存的任何内容(通常是单个对象类型)。
我还编写了一个库来确定您是否从任何给定的分配中真正获得了hugepages。这在生产应用程序中可能没有用处,但如果您尝试使用THP路线,它可以成为有用的诊断工具,因为您至少可以确定您是否获得了hugepages。
MAP_HUGETLB
标志的mmap
我假设你只需要为使用C++编写的特定应用程序创建巨大页面,否则只需更改系统的页面大小。以下方法适用于使用任何语言编写的应用程序。
In order to use huge pages for specific application you need to build your kernel for the support of huge page support. you must build kernel with CONFIG_HUGETLBFS
options
Specify page size by specifying
hugepagesz=<size>
on boot command line
To see how to set boot parameters: http://www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html
To set the no of huge pages use
# echo 20 > /proc/sys/vm/nr_hugepages
To check the huge pages (available, total, …)
# cat /proc/meminfo
When all above goes fine, now you have to work with “how to use these pages for particular application”: mount file system of type hugetlbfs
as
# mount -t hugetlbfs -o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,min_size=<value>,nr_inodes=<value> none /mnt/huge
place your application on this mount /mnt/huge
boom now your application will use page size set by you!
更多细节请查看https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
大页的优缺点:
优点:由于减少了TLB损失率,减少了页面故障,并且减少了页面表的大小以及较少的转换,因此效率高。
缺点:更多的内部碎片:内存损失,交换中的延迟增加(HUGETLBFS
页面不交换它们的映射是永久的)。更多细节请查看https://lwn.net/Articles/359158/
编辑 还有API可用于分配大页,请检查可能会有帮助
https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO
grep Huge /proc/meminfo
可以显示当前使用的巨大页面数。在我的桌面电脑(Ubuntu 15.04)上,由于内核注意到一堆连续的4k页面都在使用中,约有400MB的常规malloc
分配目前由HugePages支持。请注意,大多数台式机CPU甚至不支持1G HugePages,即使支持,将固定这么多内存也是一个更为小众的用例。参考链接:http://developerblog.redhat.com/2014/03/10/examining-huge-pages-or-transparent-huge-pages-performance/ 。 - Peter Cordes