简体   繁体   English

如何在 Linux 上为 C++ 应用程序分配“巨大”页面

[英]How to allocate "huge" pages for C++ application on Linux

I have a C++ app on Linux which is extremely latency sensitive.我在 Linux 上有一个 C++ 应用程序,它对延迟非常敏感。 My memory usage is around 2GB, so with 4kb pages and 64 TLB entries, I am going to be encountering TLB misses.我的内存使用量大约为 2GB,因此对于 4kb 页面和 64 个 TLB 条目,我将遇到 TLB 未命中。

I read in the Intel developer manuals the 2MB (or 4MB?) "huge" pages only reduce the number of TLB entries by half, so the increase in memory range offsets the reduction in TLB entries and it would be better for performance.我在英特尔开发人员手册中读到 2MB(或 4MB?)“巨大”页面只会将 TLB 条目的数量减少一半,因此内存范围的增加抵消了 TLB 条目的减少,并且性能会更好。

How do I allocate memory using "huge" pages in a C++ application?如何在 C++ 应用程序中使用“巨大”页面分配内存? Are there any trade-offs I should be aware of?是否有任何我应该注意的权衡?

My Linux is a Red Hat distribution.我的 Linux 是 Red Hat 发行版。

The "hugetlb" documentation from the kernel should help here. 内核中“hugetlb”文档在这里应该会有所帮助。

Users can use the huge page support in Linux kernel by either using the mmap system call or standard SYSV shared memory system calls (shmget, shmat).用户可以通过使用 mmap 系统调用或标准的 SYSV 共享内存系统调用(shmget、shmat)来使用 Linux 内核中的大页面支持。

And:和:

Examples例子

1) map_hugetlb: see tools/testing/selftests/vm/map_hugetlb.c 1) map_hugetlb:参见工具/测试/selftests/vm/map_hugetlb.c

2) hugepage-shm: see tools/testing/selftests/vm/hugepage-shm.c 2)hugepage-shm:请参见工具/测试/selftests/vm/hugepage-shm.c

3) hugepage-mmap: see tools/testing/selftests/vm/hugepage-mmap.c 3)hugepage-mmap:见tools/testing/selftests/vm/hugepage-mmap.c

4) The libhugetlbfs ( https://github.com/libhugetlbfs/libhugetlbfs ) library provides a wide range of userspace tools to help with huge page >usability, environment setup, and control. 4) libhugetlbfs ( https://github.com/libhugetlbfs/libhugetlbfs ) 库提供了广泛的用户空间工具来帮助处理大页面的可用性、环境设置和控制。

(These paths refer to the linux source tree). (这些路径指的是 linux 源代码树)。

So it basically boils down to:所以它基本上归结为:

  • use mmap with MAP_HUGETLB flag使用带有MAP_HUGETLB标志的mmap
  • or, map a file from the mounted hugetlb filesystem, if it exists或者,从挂载的 Hugetlb 文件系统映射文件(如果存在)

You can also try to use transparent huge page support which is available on any kernel from the last several years (at least anything in the 3.x and 4.x range and also various 2.6.x kernels).您还可以尝试使用过去几年中任何内核都提供的透明大页面支持(至少是 3.x 和 4.x 范围内的任何内核以及各种 2.6.x 内核)。

The primary benefit is that you don't need to have any special "hugetlbfs" set up, it "just works".主要好处是您不需要设置任何特殊的“hugetlbfs”,它“正常工作”。 The downside is that it is not guaranteed: the kernel may satisfy your allocations with huge pages if some conditions are met and some are available.缺点是不能保证:如果满足某些条件并且某些条件可用,内核可能会通过大页面满足您的分配。 Unlike hugetlbfs which reserves a fixed number of huge pages at startup, which are only available via specific calls, transparent huge pages carves huge pages out of the general memory pool.hugetlbfs在启动时保留固定数量的大页面(只能通过特定调用使用)不同,透明大页面从通用内存池中切割出大页面。 This requires contiguous 2MB blocks of physical memory which may become rare as the system remains up time due to physical memory fragmentation.这需要连续的 2MB 物理内存块,由于物理内存碎片导致系统保持正常运行时间,这可能会变得很少。

Furhtermore, there are various kernel tunables which affect whether you get a hugepage or not, the most important of which is /sys/kernel/mm/transparent_hugepage/enabled .此外,还有各种内核可调参数会影响您是否获得大页面,其中最重要的是/sys/kernel/mm/transparent_hugepage/enabled

Your best bet is to allocate blocks on a 2MB boundary with posix_memalign and then do a madvise(MADV_HUGEPAGE) on the allocated region before touching it for the first time.最好的办法是使用posix_memalign在 2MB 边界上分配块,然后在第一次接触之前在分配的区域上执行madvise(MADV_HUGEPAGE) It also works with variants like aligned_alloc .它也适用于诸如aligned_alloc变体。 In my experience, on systems that have /sys/kernel/mm/transparent_hugepage/enabled set to always this generally results in a hugepage.根据我的经验,在/sys/kernel/mm/transparent_hugepage/enabled设置为always这通常会导致一个大页面。 However, I've mostly used on systems with significant free memory and not-too-long uptime.但是,我主要用于具有大量可用内存且正常运行时间不太长的系统。

If you are using 2GB of memory, you could probably get a significant benefit from huge pages.如果您使用 2GB 内存,您可能会从大页面中获得显着的好处。 If you allocate that all in small blocks, eg via malloc there is a high chance transparent hugepages won't kick in, so you can also consider allocating in a THP-aware way whatever is using the bulk of your memory (often it is a single object type).如果您将所有这些都分配在小块中,例如通过malloc ,则透明大页面很有可能不会启动,因此您也可以考虑以 THP 感知的方式分配使用大量内存的任何内容(通常它是一个单个对象类型)。

I also wrote a library to determine if you actually got hugepages from any given allocation.我还编写了一个库来确定您是否真的从任何给定的分配中获得了大页面 This probably isn't useful in a production application, but it can be a helpful diagnostic if you go the route of trying to use THP since at least you can determine if you got them or not.这在生产应用程序中可能没有用,但如果您尝试使用 THP,它可能是一个有用的诊断,因为至少您可以确定是否获得了它们。

I am assuming you need huge pages only for specific application written in C++ otherwise you just change the page size of your system.我假设您只需要为用 C++ 编写的特定应用程序使用大页面,否则您只需更改系统的页面大小。 Below method will work fine for applications written in any language.以下方法适用于以任何语言编写的应用程序。

  1. 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您必须使用CONFIG_HUGETLBFS选项构建内核

  2. Specify page size by specifying通过指定指定页面大小

    hugepagesz=<size>

    on boot command line在启动命令行上

  3. To see how to set boot parameters: http://www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html查看如何设置启动参数: http : //www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html

  4. To set the no of huge pages use要设置大页面的数量,请使用

    # echo 20 > /proc/sys/vm/nr_hugepages
  5. To check the huge pages (available, total, …)检查大页面(可用,总数,...)

     # cat /proc/meminfo
  6. 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当以上一切正常时,现在您必须处理“如何将这些页面用于特定应用程序”:将类型hugetlbfs文件系统hugetlbfs

    # 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!将您的应用程序放置在此 mount /mnt/huge boom 上,现在您的应用程序将使用您设置的页面大小!

For more details check https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt有关更多详细信息,请查看https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt

Merits / demerits of huge pages:大页面的优缺点:

merits: efficiency due to reduction in TLB miss, less page faults, reduced page table size along with less translations优点:由于减少了 TLB 未命中,减少了页面错误,减少了页表大小以及更少的转换,从而提高了效率

demerits: more internal fragmentation: loss of memory, more latency in swapping ( HUGETLBFS pages does not swapp out their mapping is permanent) for more details check https://lwn.net/Articles/359158/缺点:更多的内部碎片:内存丢失,更多的交换延迟( HUGETLBFS页面不会换出它们的映射是永久性的)欲了解更多详情,请查看https://lwn.net/Articles/359158/

EDIT There is also API available to allocate huge pages plz check perhaps it helps编辑还有API可用于分配大页面请检查也许它有帮助

https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO

https://lwn.net/Articles/375096/ https://lwn.net/Articles/375096/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM