老雷看Win7(2)——NUMA
何谓NUMA(Non-Uniform Memory Access),简单来说就是在一个多CPU的系统中,每个CPU有自己的内存(local memory),当然一个CPU也可以访问其它CPU的内存,但是访问速度要比访问自己的内存慢很多。例如,下图所示的至强系统便是使用NUMA架构的。
与NUMA相对的是UMA(Uniform Memory Access),目前的很多x86系统(IA)都是UMA架构,多个CPU通过前端总线(FSB)访问主内存,每个CPU看到的主内存是一样的。
IA架构是从代号为Nehalem的CPU开始采用NUMA架构,针对台式机市场的产品便是Core i7,针对服务器市场的便是至强5500.
在NUMA架构的系统中,CPU访问本地内存比访问其它CPU的内存要快的多,所以分配内存的物理位置便不再像以前那样无关紧要,理想的情况是每个CPU大多时候都是在访问本地内存。
这个问题同样也对编写应用软件有意义,特别是内存使用量大而且注重性能的应用程序。多核时代已经让程序员失去了可以不使用多线程的免费午餐,现在看来不必关心物理内存布局的免费晚餐也要结束了。
这不,Win7已经为程序员准备好了锅碗瓢盆,从内核到API,就等着大家来“感受/忍受(?)”呢。
首先是内核的各个部件支持NUMA,不论是IO、内存管理器,还是内核本身:
ExpQueryNumaAvailableMemory |
ExpQueryNumaProcessorMap |
KiNonNumaDistance |
KiNonNumaQueryNodeCapacity |
KiNonNumaQueryNodeDistance |
|
KiNumaQueryProcessorNode |
另外在用户态引入了一系列API:
GetNumaAvailableMemoryNodeEx
GetNumaNodeNumberFromHandle
GetNumaNodeProcessorMaskEx
GetNumaProcessorNodeEx
GetNumaProximityNodeEx
GetActiveProcessorCount
GetActiveProcessorGroupCount
GetCurrentProcessorNumberEx
通过上面的API可以获取系统中的NUMA布局,通过设置进程和线程的Affinity可以选择在哪个CPU上执行:
SetThreadGroupAffinity
SetThreadIdealProcessorEx
因此,以后在设计程序时,还可以规划在哪个(些)核上运行哪个线程,以及让它使用哪个CPU上的内存,有意思吧?