gpt4 book ai didi

c - 虚拟内存映射碎片会导致性能问题吗?

转载 作者:太空宇宙 更新时间:2023-11-04 07:50:11 25 4
gpt4 key购买 nike

我有一个应用程序,我首先使用 linux mmap 系统调用创建大型匿名映射(大约 4MB)。

然后在进程执行过程中,为了尽快释放内存,我在考虑取消映射更小的内存块,这样最初是一个大块的虚拟内存映射将导致碎片化。

这是否会由于虚拟内存转换表碎片而导致性能问题,或者内核是否使用智能策略来避免这种情况?我可以不介意虚拟内存映射的碎片吗?

最佳答案

简短回答:除非您随机分配成吨成吨的最小粒度(即 4096 字节)的非连续区域。


长答案:有点,

在现代架构上,您有多个级别的虚拟内存映射(或页表,无论您喜欢哪个术语),对于 64 位架构,48 位地址空间通常有 4 级内存映射(英特尔即将推出的扩展将添加另一个级别允许将 4096 字节的页面分段为 256 字节的页面)。每次在不存在映射的区域中分配页面时,内核必须分配一个新的(通常物理上连续的;注意重点,相对而言,这是一个相当昂贵的操作) block memory 用于保存该内存空间的该区域的翻译映射。我将避免使用特定于架构的术语,而将它们称为 L0 -> L1 -> L2 -> L3,其中 L0 是表示该虚拟内存空间的根映射。这将随页面大小粒度以及不同的操作系统或架构(例如 Linux 具有 super 页面)而变化。

现在,如果您的新映射处于 L3 级别,并且具有 L3 页表,则新映射将只涉及更改该区域中的条目以指示转换。如果没有L3页表,则必须分配一个新的L3页表,并进入L2页表。依此类推,直至 L0 页表。

一些简短的笔记:

  • 每次更改映射时,通常都会有一个 TLB(翻译后备缓冲区;MMU 用于 VM->Phys 翻译的硬件缓存)失效惩罚(无论是手动还是自动)。
  • 一些页面可能不需要全部 4 个转换阶段,转换级别有特定的大小,因此 super 页面通常是一个页面,例如使用 L2 页表条目将 VM 空间的整个 block 映射到物理空间(这意味着只需要 3 个翻译级别)。
  • 各种架构使用不同的方法来减少 TLB 垃圾处理的惩罚(即 x86_64 上的 PCID;事实上,如果没有它,KPTI 等一些崩溃缓解措施会导致性能下降)。
  • 说到崩溃,某些内存范围可能具有内核或蹦床映射或异常 vector 。这些由操作系统保留。在 Spectre/Meltdown 之前的 64 位系统上,内核通常将自己映射到每个页表中。许多 ARM 处理器都有专门的机制,称为拆分页表(TTBR0/TTBR1;转换表基址寄存器 0/1)。
  • 上面的一个例子是 Linux VDSO(虚拟动态共享对象),它是由内核创建的映射。 Darwin (OSX/iOS) 对应的是 commpage (Common page)。这通常具有系统中每个进程共享的只读代码,并且具有当前时间(为了降低系统调用的成本,gettimeofday 可以从 VDSO 读取它或使用 VDSO 蹦床读取它)。
  • 当然,以上所有内容都会根据您使用的体系结构和操作系统以及您使用的操作系统版本而有所不同,因为虚拟内存管理器通常会使用各种技术来确保不会出现碎片。 但是,如果您随机请求大量小的固定映射,是的,您将有效地绕过其中的大部分,从而导致性能问题。

关于c - 虚拟内存映射碎片会导致性能问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54342812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com