6.5. NUMA 程序设计

以 NUMA 程序设计而言,目前为止说过的有关cache最佳化的所有东西也都适用。差异仅在这个层级以下才开始。NUMA 在存取定址空间的不同部分时引入不同的成本。使用均匀memory存取的话,我们能够最佳化以最小化分页错误(见 7.5 节),但这是对它而言。所有建立的分页都是均等的。

NUMA 改变这点。存取成本可能取决于被存取的分页。存取成本的差异也增加针对memory分页的局部性进行最佳化的重要性。NUMA 对于大多 SMP 机器而言都是无可避免的,因为有著 CSI 的 Intel(for x86, x86-64, and IA-64)与 AMD(for Opteron)都会使用它。随著每个处理器核数量的增加,我们很可能会看到被使用的 SMP 系统急遽减少(至少除了资料中心与有著非常高 CPU 使用率需求的人们的办公室之外)。大多家用机器仅有一个处理器就很好,因此没有 NUMA 的问题。但这一来不是说程序开发者可忽略 NUMA,再者也不表示没有相关的问题。

假如理解 NUMA 的一般化的话,也能快速意识到拓展至处理器cache的概念。在处理器核上使用相同cache的两条执行绪,会合作得比在处理器核上不共享cache的执行绪还快。这不是个杜撰的状况:

  • 早期的双核处理器没有 L2 共享。
  • 举例来说,Intel 的 Core 2 QX 6700 与 QX 6800 四核晶片拥有两个独立的 L2 cache。
  • 正如早先猜测的,由于一片晶片上的更多核、以及统一cache的渴望,我们将会有更多层的cache。

cache形成它们自己的阶层结构;执行绪在核上的摆放,对于许多cache的共享(或者没有)来说变得很重要。这与 NUMA 面对的问题并没有很大的不同,因此能够统一这两个概念。即使是只对非 SMP 机器感兴趣的人也该读一读本节。

在 5.3 节中,我们已经看到 Linux 系统核心提供许多在 NUMA 程序设计中有用 –– 而且需要 –– 的资讯。不过,收集这些资讯并没有这么简单。以这个目的而言,目前在 Linux 上可用的 NUMA 函式库是完全不足的。一个更为合适的版本正由本作者建造中。

现有的 NUMA 函式库,libnuma –– numactl 套件(package)的一部分 –– 并不提供对系统架构资讯的存取。它仅是一个对可用系统呼叫的包装(wrapper)、与针对常用操作的一些方便的介面。现今在 Linux 上可用的系统呼叫为:

mbind
选择指定memory分页的连结(binding)。
set_mempolicy
设定预设的memory连结策略。
get_mempolicy
取得预设的memory连结策略。
migrate_pages
将一组给定节点上的一个行程的所有分页迁移到一组不同的节点上。
move_pages
将选择的分页移到给定的节点、或是请求关于分页的节点资讯。

这些介面被宣告在与 libnuma 函式库一起出现的 <numaif.h> 标头档中。在我们深入更多细节之前,我们必须理解memory策略的概念。

results matching ""

    No results matching ""