下载本文的PDF版本 PDF

NUMA(非一致性内存访问):概述

NUMA变得越来越普遍,因为内存控制器越来越靠近微处理器上的执行单元。


Christoph Lameter,博士


NUMA(非一致性内存访问)是一种现象,即处理器地址空间中不同位置的内存具有不同的性能特征。在当前的处理器速度下,从处理器到内存的信号路径长度起着重要作用。信号路径长度的增加不仅增加了内存延迟,而且如果信号路径被多个处理器共享,还会迅速成为吞吐量瓶颈。内存性能差异最初在大型系统中引起注意,在这些系统中,数据路径跨越主板或机箱。这些系统需要修改后的操作系统内核,其中包含NUMA支持,该支持明确理解系统的内存拓扑属性(例如内存区域所在的机箱),以避免过长的信号路径长度。(SGI的大地址空间系统Altix和UV就是例子。这些产品的设计者不得不修改Linux内核以支持NUMA;在这些机器中,多个机箱中的处理器通过名为NUMALINK的专有互连连接。)

如今,处理器速度非常快,通常需要将内存直接连接到其所在的插槽上。从一个插槽访问另一个插槽的内存比访问本地内存有额外的延迟开销——它首先需要遍历内存互连。另一方面,来自单个处理器对本地内存的访问不仅比远程内存访问具有更低的延迟,而且不会引起互连和远程内存控制器上的争用。最好避免远程内存访问。正确的数据放置将提高整体带宽并改善内存延迟。

随着通过将内存更靠近处理器核心来提高系统性能的趋势持续发展,NUMA将在系统性能中发挥越来越重要的作用。现代处理器具有多个内存端口,并且即使核心在芯片上相对于控制器的位置不同,访问内存的延迟也会有所不同。未来几代处理器在性能上将会有越来越大的差异,因为芯片上更多的核心需要更复杂的缓存。随着这些不同类型内存的访问特性继续分化,操作系统可能需要新的功能来提供良好的性能。

今天的NUMA系统(2013年)主要在多插槽系统中遇到。如今,典型的中高端商务级服务器配备两个插槽,因此将有两个NUMA节点。内存访问(随机访问)的延迟约为100纳秒。访问远程节点上的内存会使该数字增加50%。

对性能敏感的应用程序可能需要复杂的逻辑来处理具有不同性能特征的内存。如果开发人员出于性能原因需要显式控制内存的放置,则某些操作系统为此提供API(例如,Linux、Solaris和Microsoft Windows提供用于NUMA的系统调用)。然而,操作系统中已经开发出各种启发式方法来管理内存访问,以允许应用程序透明地利用底层硬件的NUMA特性。

NUMA系统将内存分类为NUMA节点(Solaris称之为局部性组)。在一个节点中可用的所有内存对于特定的处理器都具有相同的访问特性。节点与处理器和设备具有亲和性。这些设备可以以最佳性能使用NUMA节点上的内存,因为它们是本地连接的。如果内存是从最适合处理器的NUMA节点分配的,则该内存称为节点本地内存。例如,图1中展示的NUMA系统每个插槽有一个节点,每个节点有四个核心。

A System with Two NUMA Nodes and Eight Processors

从系统中可用的NUMA节点分配内存的过程称为NUMA放置。由于放置仅影响性能,而不影响代码的正确性,因此启发式方法可以产生可接受的性能。在非缓存一致性NUMA系统的特殊情况下,情况可能并非如此,因为写入可能不会以正确的顺序到达内存中。然而,为非缓存一致性NUMA系统编码存在多重挑战。我们在这里将自己限制在常见的缓存一致性NUMA系统上。

这些讨论的重点将主要放在Linux上,因为该操作系统具有完善的NUMA功能,并且如今广泛用于对性能至关重要的环境中。作者参与了Linux中NUMA功能的创建,并且对这些功能最熟悉。

Solaris具有某种程度上可比的功能(请参阅http://docs.oracle.com/cd/E19963-01/html/820-1691/gevog.htmlhttp://docs.oracle.com/cd/E19082-01/819-2239/6n4hsf6rf/index.html;以及http://docs.oracle.com/cd/E19082-01/819-2239/madv.so.1-1/index.html),但部署的系统数量要少几个数量级。正在进行的工作是为其他类Unix操作系统添加支持,但到目前为止,这种支持主要局限于用于放置内存访问的操作系统调整参数。Microsoft Windows也开发了一个NUMA子系统,可以有效地放置内存结构,但该软件主要用于企业应用程序。具有两个NUMA节点和八个处理器的系统 NUMA节点 0 NUMA节点 1 核心 核心 核心 核心 互连 核心 核心 核心 核心 而不是高性能计算。企业级应用程序的内存访问速度要求通常比高性能计算中更宽松,因此在Windows中处理NUMA内存所花费的精力比Linux中少。

操作系统如何处理NUMA内存

现代生产操作系统允许管理NUMA的方式主要分为以下几类:接受性能不匹配、硬件内存条带化、启发式内存放置、静态NUMA配置和应用程序控制的NUMA放置。

忽略差异

由于NUMA放置是一种尽力而为的方法,因此一种选择是简单地忽略可能的性能优势,而将所有内存都视为不存在性能差异。这意味着操作系统不知道内存节点。系统可以正常运行,但性能会因内存的分配方式而异。本地访问和远程访问之间的差异越小,此选项就越可行。

这种方法允许软件和操作系统在不修改的情况下运行。通常,当首次使用具有NUMA特性的系统时,这是系统软件的初始方法。性能将不是最佳的,并且每次机器和/或应用程序运行时都可能不同,因为性能关键段的内存分配取决于系统配置和启动时的时序效应。

硬件内存条带化

某些机器可以设置从内存地址到节点中缓存行的映射,使得地址空间中的连续缓存行取自不同的内存控制器(缓存行级别的交错)。结果,NUMA效应被平均化(因为大于缓存行的结构将使用多个NUMA节点上的缓存行)。与仅忽略差异的方法相比,整体系统性能更具确定性,并且操作系统仍然不需要知道内存性能的差异,这意味着操作系统中不需要NUMA支持。由于访问分散在所有可用的NUMA节点中,因此降低了节点过载的危险。

缺点是互连始终处于使用状态。性能永远不会是最佳的,因为条带化意味着经常从远程NUMA节点访问缓存行。

应用程序的启发式内存放置

如果操作系统是NUMA感知的(在Linux下,必须在编译时启用NUMA,并且BIOS或固件必须提供NUMA内存信息才能使NUMA功能生效;可以使用内核参数在运行时禁用和控制NUMA),则最好采取措施,使应用程序能够以最小化信号路径长度的方式分配内存,从而提高性能。操作系统必须采用一种策略,以尽可能地最大化许多应用程序的性能。大多数应用程序使用启发式方法运行时性能都会得到提高,尤其是与前面讨论的方法相比。NUMA感知的操作系统从固件确定内存特性,因此可以调整其自身的内部操作以适应内存配置。但是,这种调整需要编码工作,因此只有操作系统的性能关键部分倾向于针对NUMA亲和性进行优化,而性能不太关键的组件倾向于假设所有内存都是相等的。

操作系统最常见的假设是应用程序将在本地节点上运行,并且应优先使用来自本地节点的内存。如果可能,进程请求的所有内存都将从本地节点分配,从而避免使用交叉连接。但是,如果所需的处理器数量高于插槽上可用的硬件上下文数量(当必须使用两个NUMA节点上的处理器时);如果应用程序使用的内存超过节点上可用的内存;或者如果应用程序程序员或调度程序在内存分配发生后决定将应用程序线程移动到不同插槽上的处理器,则此方法将不起作用。

通常,小型Unix工具和小型应用程序使用此方法效果很好。利用系统总内存的很大一部分和系统上大多数处理器的大型应用程序通常会受益于利用NUMA的显式调整或软件修改。

大多数类Unix操作系统都支持此操作模式。值得注意的是,FreeBSD和Solaris具有放置内存结构以避免瓶颈的优化措施。FreeBSD可以在多个节点上轮询放置内存,以便平均延迟。这使FreeBSD在无法在BIOS或硬件级别进行缓存行交错的系统上更好地工作(FreeBSD 10计划增加NUMA支持)。Solaris还为每个局部性组复制重要的内核数据结构。

应用程序的特殊NUMA配置

操作系统提供配置选项,允许操作员告知操作系统应用程序不应使用关于内存放置的默认假设运行。可以在不修改代码的情况下为应用程序建立内存分配策略。

Linux下存在命令行工具,可以设置策略来确定内存亲和性(taskset,numactl)。Solaris具有可调整的参数,用于控制操作系统如何从局部性组分配内存。这些参数大致类似于Linux的进程内存分配策略。

应用程序控制NUMA分配

应用程序可能希望对操作系统如何处理其每个内存段的分配进行细粒度控制。为此,存在系统调用,允许应用程序指定哪个内存区域应使用哪些策略进行内存分配。

主要性能问题通常涉及大型结构,这些结构由来自所有内存节点的应用程序线程频繁访问,并且通常包含需要在所有线程之间共享的信息。这些最好使用交错放置,以便对象分布在所有可用节点上。

Linux如何处理NUMA?

Linux以区域的方式管理内存。在非NUMA Linux系统中,区域用于描述支持无法对所有内存位置执行DMA(直接内存访问)的设备所需的内存范围。区域还用于标记其他特殊需求的内存,例如可移动内存或需要显式映射才能被内核访问的内存(HIGHMEM),但这与本文讨论无关。启用NUMA后,将创建更多内存区域,并且它们也与NUMA节点关联。一个NUMA节点可以有多个区域,因为它可能能够服务于多个DMA区域。可以通过查看以下内容来确定Linux如何安排内存/proc/zoneinfo。区域的NUMA节点关联允许内核做出涉及相对于核心的内存延迟的决策。

在启动时,Linux将通过固件提供的ACPI(高级配置和电源接口)表检测内存的组织结构,然后根据需要创建映射到NUMA节点和DMA区域的区域。然后从区域进行内存分配。如果一个区域中的内存耗尽,则会发生内存回收:系统将扫描最近最少使用的页面,尝试释放一定数量的页面。显示各个节点/区域中内存当前状态的计数器也可以在/proc/zoneinfo中看到。图2显示了区域/节点中的内存类型。区域/节点中的内存类型 空闲内存 未映射页缓存(例如,缓存的磁盘内容) 映射到进程的页面(例如,文本段,mmap文件) 匿名页面(例如,堆栈,堆) 脏页或回写页(例如,磁盘I/O) 不可驱逐页面(例如,mlock) 内核、驱动程序和不可回收的slab内存

Types of Memory in a Zone/Node

内存策略

NUMA下如何分配内存由内存策略决定。可以为进程地址空间中的内存范围、进程或整个系统指定策略。进程策略覆盖系统策略,特定内存范围的策略覆盖进程的策略。

最重要的内存策略是

节点本地。 从代码当前正在执行的位置的本地内存节点进行分配。

交错。 轮询进行分配。首先从节点0分配一个页面,然后从节点1分配一个页面,然后再从节点0分配一个页面,依此类推。交错用于为可能从系统中多个处理器访问的结构分配内存访问,以便在互连和每个节点的内存上实现均匀负载。

还有其他特殊情况下使用的内存策略,为简洁起见,此处未提及。刚刚提到的两个策略通常是最有用的,操作系统默认使用它们。如果系统已启动并正在运行,则节点本地是默认的分配策略。

Linux内核将在启动时默认使用交错策略。在引导期间创建的内核结构分布在所有可用节点上,以避免在进程需要访问操作系统结构时在单个内存节点上施加过大的负载。当第一个用户空间进程(init守护程序)启动时,系统默认策略更改为节点本地。

进程的所有内存段的活动内存分配策略(以及显示实际从哪个节点分配了多少内存的信息)可以通过确定进程的id然后查看/proc/<pid>/numa_maps.

进程启动时的基本操作

进程从其父进程继承其内存策略。大多数时候,策略保持默认值,这意味着节点本地。当进程在处理器上启动时,将从本地NUMA节点为该进程分配内存。进程的所有其他分配(通过增加堆、页面错误、mmap等等)也将从本地NUMA节点满足。

Linux调度程序将尝试在负载均衡期间保持进程缓存热。这意味着调度程序的首选是将进程保留在共享L1处理器缓存的处理器上,然后在共享L2的处理器上,然后在共享L3的处理器上,以及进程上次运行的处理器上。如果存在超出此范围的不平衡,则调度程序会将进程移动到同一NUMA节点上的任何其他处理器。

作为最后的手段,调度程序会将进程移动到另一个NUMA节点。此时,代码将在一个节点的处理器上执行,而移动之前分配的内存已在旧节点上分配。进程的大多数内存访问将是远程的,这将导致进程的性能下降。

最近有一些工作使调度程序具有NUMA感知能力,以确保可以将进程的页面移回本地节点,但该工作仅在Linux 3.8及更高版本中可用,并且被认为不成熟。有关事态的更多信息,可以在Linux内核邮件列表和lwn.net上的文章中找到。

回收

Linux通常会分配所有可用内存,以便缓存可能再次使用的数据。当内存开始不足时,将使用回收来查找当前未使用或不太可能很快使用的页面。从内存中逐出页面并在需要时重新获取页面的工作量因页面类型而异。Linux倾向于从磁盘中逐出未映射到任何进程空间的页面,因为它很容易删除对该页面的所有引用。如果稍后需要该页面,可以从磁盘重新读取该页面。映射到进程地址空间的页面需要先从该地址空间中删除该页面,然后才能重用该页面。不是磁盘页面副本的页面(匿名页面)只有在首先写入交换空间(昂贵的操作)后才能逐出。还有一些页面根本无法逐出,例如mlocked()内存或用于内核数据的页面。

因此,回收对系统的影响可能会有所不同。在NUMA系统中,每种类型的内存将在每个节点上分配。每个节点上的可用空间量将有所不同。因此,如果存在内存请求,并且使用本地节点上的内存需要回收,但另一个节点有足够的内存来满足请求而无需回收,则内核有两种选择

• 在本地节点上运行回收过程(导致内核处理开销),然后将节点本地内存分配给进程。

• 只需从不需要回收过程的另一个节点分配。内存将不是节点本地的,但我们避免了频繁的回收过程。当所有区域的空闲内存不足时,将执行回收。这种方法降低了回收的频率,并允许在单个过程中完成更多的回收工作。

对于小型NUMA系统(例如典型的双节点服务器),内核默认为第二种方法。对于较大的NUMA系统(四个或更多节点),内核将尽可能执行回收以获取节点本地内存,因为延迟对进程性能的影响更大。

内核中有一个旋钮,用于确定如何在/proc/sys/vm/zone_reclaim中处理这种情况。值为0表示不应进行本地回收。值为1告诉内核应运行回收过程,以避免从其他节点分配。在启动时,根据系统中最大的NUMA距离选择一种模式。

如果区域回收已打开,则内核仍会尝试使回收过程尽可能轻量化。默认情况下,回收将仅限于未映射的页缓存页面。可以通过设置/proc/sys/vm/min_unmapped_ratio来进一步降低回收过程的频率,该值表示系统运行回收过程必须包含未映射页面的内存百分比。默认值为1%。

可以通过启用脏页的回写或匿名页面的交换来使区域回收更具侵略性,但在实践中,这样做通常会导致严重的性能问题。

基本NUMA命令行工具

用于为进程设置NUMA执行环境的主要工具是numactl. Numactl可用于显示系统NUMA配置,并控制共享内存段。可以将进程限制为一组处理器以及一组内存节点。Numactl例如,可以使用它来避免节点之间的任务迁移或将内存分配限制为特定节点。请注意,如果分配受到限制,则可能需要额外的回收过程。这些情况不受区域回收模式的影响,因为分配由内存策略限制为一组特定的节点,因此内核无法简单地从另一个NUMA节点选择内存。

另一个经常用于NUMA的工具是taskset。它基本上只允许将任务绑定到处理器,因此仅具有numactl功能的一个子集。Taskset在非NUMA环境中被大量使用,其熟悉性导致开发人员更喜欢使用taskset而不是numactl在NUMA系统上。

NUMA信息

有许多方法可以查看有关系统和当前运行的各种进程的NUMA特性的信息。可以使用numactl -hardware查看系统的硬件NUMA配置。这包括SLIT(系统局部性信息表)的转储,该表显示了NUMA系统中访问不同节点的成本。下面的示例显示了一个具有两个节点的NUMA系统。本地访问的距离为10。在此系统上,远程访问的成本是本地访问的两倍(20)。这是惯例,但一些供应商(尤其是对于双节点系统)的做法是简单地报告10和20,而不管实际的内存延迟差异如何。


$ numactl --hardware
可用节点:2 个 (0-1)
节点 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
节点 0 大小: 131026 MB
节点 0 空闲: 588 MB
节点 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
节点 1 大小: 131072 MB
节点 1 空闲: 169 MB
节点距离
节点  0  1
  0: 10 20
  1: 20 10

Numastat是另一个用于显示有多少分配从本地节点满足的工具。特别值得关注的是numa_miss计数器,它指示系统从不同的节点分配内存以避免回收。这些分配也计入其他节点。其余计数是有意的异地节点分配。异地节点内存量可以用作指导,以了解内存分配给系统上运行的进程的有效程度。


$ numastat
                节点0       节点1
numa_hit        13273229839 4595119371
numa_miss       2104327350  6833844068
numa_foreign    6833844068  2104327350
interleave_hit  52991       52864
local_node      13273229554 4595091108
other_node      2104327635  6833872331

如何将内存分配给进程可以通过/proc/<pid>/numa_maps:


# cat /proc/1/numa_maps
7f830c175000 默认 anon=1 dirty=1 active=0 N1=1
7f830c177000 默认 file=/lib/x86_64-linux-gnu/ld-2.15.so anon=1 dirty=1 active=0 N1=1
7f830c178000 默认 file=/lib/x86_64-linux-gnu/ld-2.15.so anon=2 dirty=2 active=0 N1=2
7f830c17a000 默认 file=/sbin/init mapped=18 N1=18
7f830c39f000 默认 file=/sbin/init anon=2 dirty=2 active=0 N1=2
7f830c3a1000 默认 file=/sbin/init anon=1 dirty=1 active=0 N1=1
7f830dc56000 默认 heap anon=223 dirty=223 active=0 N0=52 N1=171
7fffb6395000 默认 stack anon=5 dirty=5 active=1 N1=5

输出显示了策略的虚拟地址,然后显示了有关内存范围的NUMA特性的一些信息。Anon表示页面在磁盘上没有关联的文件。Nx显示各个节点上的页面数。

有关系统中内存整体使用情况的信息可在/proc/meminfo中获得。相同的信息也可在每个NUMA节点的/sys/devices/system/node/node<X>/meminfo中获得。许多其他信息可从meminfo所在的目录中获得。可以通过检查和写入该目录中关键文件的值来压缩内存、获取距离表以及管理巨页和mlocked页面。

首次访问策略

为进程或地址范围指定内存策略不会导致任何内存分配,这通常会使新手感到困惑。内存策略指定了系统需要为虚拟地址分配内存时应该发生什么。进程内存空间中尚未访问或为零的页面没有分配内存。当进程访问或写入尚未填充的地址(页面错误)时,处理器将生成硬件故障。在内核处理页面错误期间,页面被分配。然后重新启动导致错误的指令,并将能够根据需要访问内存。

因此,重要的是分配发生时生效的内存策略。这称为首次访问。首次访问策略指的是基于某些进程首次以某种方式使用页面时生效的策略来分配页面的事实。

页面上的有效内存策略取决于分配给内存范围的内存策略或与任务关联的内存策略。如果页面仅由单个线程使用,则对于将遵循哪个策略没有歧义。但是,页面通常由多个线程使用。它们中的任何一个都可能导致页面被分配。如果线程具有不同的内存策略,则结果页面似乎会以令人惊讶的方式为稍后也看到同一页面的进程分配。

例如,文本段通常由使用同一可执行文件的所有进程共享。如果文本段中的页面已在内存中,则内核将使用该页面,而与在范围上设置的内存策略无关。因此,文本段中页面的第一个用户将确定其位置。库通常在二进制文件之间共享,尤其是C库将被系统上几乎所有进程使用。因此,许多最常用的页面是在启动期间分配的,当时首次运行使用C库的二进制文件。页面将在那时在特定的NUMA节点上建立,并在系统运行期间保持在那里。

首次访问现象限制了进程对其数据的放置控制。如果到文本段的距离对进程性能有重大影响,则必须在内存中移动错位的页面。由于较早的任务已将数据带入内存,因此内存可能看起来已在当前任务的内存策略不允许的NUMA节点上分配。

移动内存

Linux具有移动内存的功能。进程空间中内存的虚拟地址保持不变。只有数据的物理位置被移动到不同的节点。可以通过查看/proc/<pid>/numa_maps移动之前和之后

将进程的所有内存迁移到一个节点可以通过避免交叉连接访问来优化应用程序性能,如果系统已将页面放置在其他NUMA节点上。但是,普通用户只能移动仅由该进程引用的进程页面(否则,用户可能会干扰其他用户拥有的进程的性能优化)。只有root才具有移动进程所有页面的能力。

很难确保所有页面都是进程本地的,因为某些文本段被大量共享,并且对于文本段的地址可能只有一个页面支持。C库和其他大量共享的库尤其如此。

Linux有一个migratepages命令行工具,用于通过指定pid以及源节点和目标节点来手动移动页面。将扫描进程的内存以查找当前在源节点上分配的页面。它们将被移动到目标节点。

NUMA调度

在Linux 3.8之前,Linux调度程序没有进程内存页面放置的概念。关于迁移进程的决策是基于对进程内存缓存热度的估计做出的。如果Linux调度程序将进程的执行移动到另一个NUMA节点,则该进程的性能可能会受到损害,因为其内存现在需要通过交叉连接访问。一旦移动完成,调度程序将估计进程内存在远程节点上是缓存热的,并尽可能长时间地将进程保留在那里。结果,希望获得最佳性能的管理员认为最好不要让Linux调度程序干扰内存放置。进程通常使用taskset固定到一组特定的处理器,或者使用cpusets功能对系统进行分区,以使应用程序保持在NUMA节点边界内。

在Linux 3.8中,采取了第一步来解决这种情况,方法是合并一个框架,该框架最终将使调度程序能够考虑页面放置,并可能自动将页面从远程节点迁移到本地节点。但是,仍然需要大量的开发工作,并且现有方法并不总是能提高负载性能。这是2013年4月编写本节时的状况。有关最新信息,请访问Linux内核邮件列表http://vger.kernel.orgLinux Weekly Newshttp://lwn.net)上的文章。例如,请参阅http://lwn.net/Articles/486858/

结论

NUMA支持已经在各种操作系统中存在一段时间了。Linux中的NUMA支持自2000年初以来一直可用,并且一直在不断完善。内核NUMA支持通常可以优化进程执行,而无需用户干预,并且在大多数用例中,操作系统可以简单地在NUMA系统上运行,为典型应用程序提供体面的性能。

当操作系统提供的启发式方法无法为最终用户提供令人满意的应用程序性能时,通过工具和内核配置实现的特殊 NUMA 配置就发挥作用了。这种情况通常出现在高性能计算、高频交易和实时应用中,但最近这些问题对于常规企业级应用也变得越来越重要。传统上,NUMA 支持需要关于应用程序和硬件的专门知识,以便使用操作系统提供的旋钮进行适当的调优。最近的发展(特别是围绕 Linux NUMA 调度器)可能会使操作系统能够随着时间的推移自动正确地平衡 NUMA 应用程序负载。

NUMA 的使用需要以可能实现的性能提升为指导。本地和远程内存访问之间的差异越大,NUMA 放置带来的好处就越大。NUMA 延迟差异是由于内存访问造成的。如果应用程序不依赖于频繁的内存访问(例如,因为处理器缓存吸收了大部分内存操作),NUMA 优化将不起作用。此外,对于 I/O 密集型应用,瓶颈通常是设备而不是内存访问。为了使用 NUMA 优化应用程序,需要了解硬件和软件的特性。

延伸阅读

McCormick, P. S., Braithwaite, R. K., Feng, W. 2011. 多核 NUMA 架构中的经验内存访问成本模型。弗吉尼亚理工大学计算机科学系。

Hacker, G. 2012. 在 RHEL 6 上使用 NUMA;https://127.0.0.1/summit/2012/pdf/2012-DevDay-Lab-NUMA-Hacker.pdf

Kleen, A. 2005. Linux 的 NUMA API。Novell;http://developer.amd.com/wordpress/media/2012/10/LibNUMA-WP-fv1.pdf

Lameter, C. 2005. Linux/NUMA 系统上的有效同步。Gelato 会议;http://www.lameter.com/gelato2005.pdf

Lameter, C. 2006. 远程和本地内存:Linux/NUMA 系统中的内存。Gelato 会议:SGI。Li, Y., Pandis, I., Mueller, R., Raman, V., Lohman, G. 2013. NUMA 感知算法:数据混洗案例。威斯康星大学麦迪逊分校 / IBM Almaden 研究中心。Love, R. 2004. Linux 内核开发。 印第安纳波利斯:Sams Publishing。

Oracle. 2010. 内存和线程放置优化开发者指南http://docs.oracle.com/cd/E19963-01/html/820-1691/

Schimmel, K. 1994. 现代架构的 Unix 系统:内核程序员的对称多处理和缓存。 Addison-Wesley。

喜欢还是讨厌?请告诉我们 [email protected]

Christoph Lameter 专注于高性能计算和高频交易技术。作为一名操作系统设计师和开发者,他一直在开发 Linux 的内存管理技术,以提高性能并减少延迟。他喜欢颠覆现有行业并促使新的开发社区出现的新技术和新思维方式。

© 2013 1542-7730/13/0700 $10.00 12

acmqueue

最初发表于 Queue vol. 11, no. 7
数字图书馆 中评论这篇文章





更多相关文章

Michael Mattioli - 客户端计算硬件中的 FPGA
FPGA(现场可编程门阵列)具有非凡的通用性。它们被广泛应用于各种应用和行业,在这些应用和行业中,使用 ASIC(专用集成电路)的经济可行性较低。尽管设计师在将 FPGA 集成到设备中时面临面积、成本和功耗方面的挑战,但它们提供了显着的安全性和性能优势。其中许多优势可以在客户端计算硬件(如笔记本电脑、平板电脑和智能手机)中实现。


Bill Hsu, Marc Sosnick-Pérez - 实时 GPU 音频
如今的 CPU 能够为许多流行的应用程序提供实时音频支持,但一些计算密集型音频应用程序需要硬件加速。本文着眼于一些实时声音合成应用程序,并分享了作者在 GPU(图形处理器)上实现它们的经验。


David Bacon, Rodric Rabbah, Sunil Shukla - 面向大众的 FPGA 编程
当考察硬件如何影响计算性能时,我们看到频谱的一端是 GPP(通用处理器),另一端是 ASIC(专用集成电路)。处理器具有高度可编程性,但在功耗和性能方面通常效率低下。ASIC 实现专用和固定功能,并提供最佳的功耗和性能特性,但任何功能上的更改都需要完全(且极其昂贵地)重新设计电路。


Andrew Danowitz, Kyle Kelley, James Mao, John P. Stevenson, Mark Horowitz - CPU 数据库:记录微处理器历史
1971 年 11 月,英特尔推出了世界上第一款单芯片微处理器 Intel 4004。它拥有 2300 个晶体管,运行频率高达 740 KHz,每秒可执行 60,000 条指令,同时功耗为 0.5 瓦。随后的四十年见证了计算能力的指数级增长,这一趋势使得气候建模、蛋白质折叠和计算愤怒的小鸟的实时弹道轨迹等各种应用成为可能。





© 保留所有权利。

© . All rights reserved.