我在 https://en.wikipedia.org/wiki/Fragmentation_(computing) 上读到了这段话:“但是,如果工作集是碎片化的,那么它将无法容纳 64 个页面,并且执行速度会因以下原因而变慢:颠簸:在操作过程中,页面将被重复添加到 TLB 中并从 TLB 中删除。”
我很困惑为什么物理内存碎片会导致“不适合64页”。我理解即使物理页有碎片,仍然应该有64个物理页和虚拟页占用64个TLB条目。在这种情况下,缓存命中或未命中不应该与外部碎片无关吗?有人可以帮我澄清一下吗?
我认为这不是在谈论物理内存碎片,而是更多地谈论缓存与 TLB 行为。本文中的示例是:“程序具有 256 KiB 的工作集,并且正在具有 256 KiB 缓存的计算机上运行”和 64 个 TLB 条目。
如果我们假设这 256 KB 全部整齐地打包成 64 个 4kB 虚拟页面,那么它们将由 64 个 4kB 物理页面支持;所有映射都将适合 TLB(好吧,也许会;这取决于 TLB 架构),并且所有数据也将适合缓存。
如果我们假设已经发生了一些碎片,并且使用的数据现在分布在 4 kB 块中,块之间有 4 kB 孔,那么我们仍然只获得 64 个活跃使用的虚拟和物理页面。总体情况与第一个示例相比没有太大变化 - 整个数据仍然适合 TLB/缓存。
如果我们现在假设已经发生了一些碎片,并且使用的数据现在均匀分布在 1 kB 块中,它们之间有未使用的 1 kB 孔。因此,数据大小仍然是 256 kB,它们仍然适合缓存(因为每个缓存行通常为 64 字节宽),但数据现在分布在 128 个虚拟和物理页中,严重的 TLB 抖动将是不可避免的。
本文的这一部分有点误导,因为工作集有各种可能的定义。我认为他们的工作定义是“经常访问的数据量,以字节为单位”——根据这个定义,这篇文章是有意义的。然而,工作集通常是在页面粒度上进行测量的,因为分配给进程的虚拟页面数量(事实上,甚至维基文章从本文链接说“通常所讨论的信息单元被认为是内存页面”) 。根据这个定义,256 KiB 的工作集将不可避免地使用 64 个 4 KiB 页面,整个示例就会崩溃。