处理复杂的内存情况
Jérôme Glisse 认为,Linux 内核是时候认真解决在单个运行系统上安装多种不同类型内存的问题了。存在主系统内存和设备专用内存,以及关于在何时何种情况下使用哪种内存的相关层级结构。Jérôme 说,这种复杂的新情况实际上现在已成为常态,应该这样对待。
各种 CPU、设备和 RAM 芯片之间的物理连接(即总线拓扑)也具有相关性,因为它会影响每个组件的不同速度。
Jérôme 希望明确表示,他的提议超越了处理异构 RAM 的现有努力。他希望考虑到各种硬件及其拓扑关系,以便从给定的系统中尽可能榨取最高的性能。他说:
激进变革的原因之一是 GPU 或 FPGA 等加速器的进步意味着 CPU 不再是唯一进行计算的部件。应用程序越来越普遍地混合和匹配使用不同的加速器来执行其计算。因此,我们不能再满足于以 CPU 为中心和扁平化的系统视图,例如 NUMA 和 NUMA 距离。
他发布了一些补丁来实现几个不同的目标。首先,他希望向用户空间公开总线拓扑和内存种类,作为一个清晰的 API,以便内核和用户应用程序都可以最大程度地利用给定系统上的特定硬件配置。他说,这其中一部分必须考虑到并非系统上的所有内存始终对所有设备、CPU 或用户都同样可用。
为了完成所有这些,他的补丁首先确定了四个基本元素,这些元素可用于构建给定系统上 CPU、内存和总线拓扑的任意复杂图。
这些元素包括“目标”,即任何类型的内存;“发起者”,即 CPU 或任何其他可能访问内存的设备;“链接”,即目标和发起者之间的任何类型的总线连接;以及“桥接器”,可以将发起者组连接到远程目标。
带宽和延迟等属性将与它们相关的链接和桥接器相关联。并且,系统的整个图将通过 SysFS
层次结构中的文件向用户空间公开。
此外,Jérôme 的补丁还提供了一种表达内存策略的方法。系统的内存策略是它用来决定为给定任务使用哪种内存的机制。例如,它可能首先使用更快的内存,仅在快速内存已满时才使用较慢的内存。但是,内核当前的内存策略是基于每个 CPU 组织的,Jérôme 认为这还不够好。但是,他也承认,尝试直接更改内核基础设施的这方面可能会破坏许多现有代码。为了解决这个问题,他的补丁添加了一个全新的内存策略 API,新用户代码可以利用它,而旧用户代码可以简单地忽略它。
Aneesh Kumar 回应了所有这些,特别是赞扬了 Jérôme 将新 API 与旧 API 分开的方法。但 Aneesh 说,“但这不也是缺点吗?我们现在有多个实体在跟踪 CPU 和内存。”
Aneesh 还想确认,“一旦我们有了这些不同类型的目标,理想情况下,系统应该能够根据访问的亲和性将它们放置在理想的位置。即,我们应该自动放置内存,以便发起者可以最佳地访问目标。”
Jérôme 似乎原则上同意这一点,但他似乎也觉得,使任何这些自动化仍然不能保证。他认为,第一步是公开 API 和数据结构,然后看看可以完成什么。
与此同时,Dave Hansen 指出,内核中已经存在处理异构内存的元素。Dave 说,固件中专门存在 HMAT(异构内存属性表)来向内核表达拓扑结构。Dave 还说,NUMA(非统一内存访问)已经是内核的一部分,并且没有闲置。此外,他指出 ACPI(高级配置和电源接口)规范已正式采用 NUMA,并且有 Linux 开发人员积极贡献补丁来支持这一点。
因此,Dave 并不立即热衷于放弃在一个方向上正在进行的势头,而是接受 Jérôme 的完全朝着新方向发展的激进解决方案。
但是,Jérôme 回复说,他并没有试图推翻现有的工作或任何利用 HMAT 的内核补丁。他说,所有这些本身仍然有用。但他补充说:
我不知道如何发展 NUMA 来支持设备内存。[...] 我无法将设备内存公开为 NUMA 节点,因为设备内存目前在 AMD 和 Intel 平台上不具备缓存一致性。[...] 在某些情况下,CPU 完全看不到该内存,这是您无法在当前 NUMA 节点中表达的。
Dave 的语气稍有缓和,他回复道:
是的,我们的 NUMA 机制用于管理内核自身在“正常”分配器中管理的内存,并支持全套功能。这有很多含义,例如内存是缓存一致的并且可以从任何地方访问。
HMAT 补丁仅理解这种“正常”内存,这就是我们扩展现有 /sys/devices/system/node 基础设施的原因。
这个系列的目标更加激进,它理解每个内存目标与每个内存发起者的连接,无论谁在管理内存,谁可以访问它,或者它可以用于什么。
理论上,HMS 可以用于我们正在使用 /sys/devices/system/node 所做的一切,只要它以某种方式与现有的 NUMA 基础设施联系起来。
Jérôme 同意以上所有观点,Dave 似乎也赞同 Jérôme 的方法。但是,他确实有一些实际的反对意见。其中之一,他说:
我们在 x86 上支持 1024 个 NUMA 节点。ACPI HMAT 表达了每个节点之间的连接。假设每个节点都有一些 CPU 和一些内存。
这意味着我们将在 sysfs 中有 1024 个目标目录,在 sysfs 中有 1024 个发起者目录,以及 1024*1024 个链接目录。或者,内核是否会负责将固件提供的信息“编译”成更易于管理的链接数量?
很久以前,某个白痴犯了一个错误,每个 128MB 内存都有一个 sysfs 目录,现在我们有成千上万个 /sys/devices/system/memory/memoryX 目录。这很难管理。这是否有可能重蹈覆辙?
Dave 还担心,如果 Jérôme 继续推进他的补丁,可能需要四到五年才能解决所有问题,在这种情况下,内存管理的某些部分将被瓶颈所限制,等待这些解决方案,而使用现有的 NUMA 项目本可以更快地解决这些问题。
此外,Dave 很好奇 Jérôme 的代码将如何扩展。他说,“表示一台笔记本电脑很容易,但它可以扩展到我们期望在未来 20 年内遇到的最大系统吗?这个 ABI 将存在 20 年。”
此时,Jérôme 和 Dave 与其他几个人加入了讨论,并开始深入探讨技术细节、进一步的反对意见以及可能从 Jérôme 的工作中得出的解决方案。最终,这些补丁似乎并没有对现有的内存处理方法构成威胁,并且 Jérôme 将获得来自 NUMA 相关项目的支持——或至少是容忍。
我喜欢这次讨论的地方首先是,一位开发人员有了一个似乎与当前思维背道而驰的宏伟想法,但却解决了他认为真实存在的问题。其次,问题的另一方的开发人员实际上对新方法感兴趣,并愿意认真对待它,而不是否定它。
此外,硬件资源的整体方向确实变得非常奇怪。内核试图从系统上的各种设备中榨取绝对的一切——甚至到了超越这些设备认为它们会被使用的方式的程度!然后,一旦内核开始以这种方式使用它们,其他设备就会出现,这些设备使用了内核的新基础设施。因此,我们最终会陷入某种疯狂的境地,需要像 Jérôme 提出的那样疯狂的解决方案。
注意:如果您在上面被提及并希望在评论区上方发布回复,请将您的回复文本发送至 ljeditor@linuxjournal.com。