深入浅出Linux NUMA

一、什么是NUMA

NUMA的全称是Non-Uniform Memory Access,中文翻译为非一致性内存访问,是一种在多处理器系统中使用的内存架构和访问优化技术。

在NUMA架构下,多个处理器可以共享一部分内存,但是访问不同的内存区域的时间不同,这就是“非一致性”的含义。为了优化访问性能,Linux系统对NUMA架构提供了一些支持和优化手段。


/*
 * 查看当前系统是否支持NUMA
 */
# cat /proc/cpuinfo | grep -i numa

二、为什么要使用NUMA

在单处理器系统中,所有内存都是一致的,处理器可以随意访问任何内存位置,不需要花费额外的时间。但是在多处理器系统中,不同处理器访问距离较远的内存位置的时间会变得很长,这就导致了可观的性能下降。

NUMA架构通过将内存分成多个节点来优化内存访问性能。每个节点拥有自己的内存,同时还能够访问其他节点的内存。这样,处理器只需要访问与自己所在节点相邻的内存节点,可以有效减少访问时间。

三、如何使用NUMA

1. 绑定进程

在NUMA架构下,Linux系统提供了一个针对进程的优化手段:CPU和内存绑定。通过指定进程运行的CPU和内存节点,可以提高进程的性能。


/*
 * 绑定当前进程到CPU 0 和 NUMA节点 0
 */
# numactl --cpubind=0 --membind=0 <command>

2. NUMA感知分配

NUMA感知分配是一种对内存分配进行优化的手段。在NUMA感知分配中,内存会被分配到最适合它的节点上,而不是默认的全局节点。


/*
 * 为指定进程分配一块大小为2GB的内存,并将其分配到NUMA节点1上
 */
# numactl --membind=1 <command>
# ptr = numa_alloc_onnode(2<<30, 1);  // 用于内存分配的C函数

3. NUMA感知调度

NUMA感知调度是一种优化调度用于NUMA架构的进程的手段。在NUMA感知调度中,系统会尽量将进程调度到与它绑定的CPU和内存节点相同的CPU上。


/*
 * 设置NUMA感知调度
 */
# echo 1 > /proc/sys/kernel/numa_balancing
# echo 1 > /proc/sys/kernel/sched_numa_placement

四、NUMA带来的性能提升举例

下面是在NUMA架构下启用NUMA感知分配和调度的例子。在这个例子中,通过在多个NUMA节点上启用线程,从而使用了多个处理器和多个内存节点,大大提高了程序的性能。


#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <numa.h>

#define THREAD_NUM 4
#define MEM_SIZE (1<<30)

void* thread_func(void* arg) {
    int node_id = *(int*)arg;
    char* mem;
    mem = (char*)numa_alloc_onnode(MEM_SIZE, node_id);
    for(long i = 0; i < MEM_SIZE; i++)
        mem[i] = 1;
}

int main() {
    int node_num = numa_max_node() + 1;
    pthread_t tids[THREAD_NUM];
    for(int i = 0; i < THREAD_NUM; i++) {
        pthread_create(&tids[i], NULL, thread_func, (void*)&(i % node_num));
    }
    for(int i = 0; i < THREAD_NUM; i++)
        pthread_join(tids[i], NULL);
    return 0;
}

五、总结

NUMA是一种优化多处理器系统中内存访问性能的架构和技术。在Linux系统中,我们可以使用CPU和内存绑定、NUMA感知分配和调度等手段来进行性能优化。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/237742.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 12:07
下一篇 2024-12-12 12:07

相关推荐

  • 如何在Linux中添加用户并修改配置文件

    本文将从多个方面详细介绍在Linux系统下如何添加新用户并修改配置文件 一、添加新用户 在Linux系统下创建新用户非常简单,只需使用adduser命令即可。使用以下命令添加新用户…

    编程 2025-04-27
  • 如何解决linux jar包 invalid or corrupt jarfile问题

    对于许多开发人员和系统管理员在Linux环境下使用Java开发过程中遇到的一个常见的问题是 invalid or corrupt jarfile(无效或损坏的jar文件)错误。当您…

    编程 2025-04-27
  • 在Linux上安装JRE并配置环境变量

    本文将从以下几个方面为您详细阐述如何在Linux系统上,通过自己账户安装JRE,并且配置环境变量。 一、安装JRE 在进行安装前,我们需要下载JRE的安装包并解压,可以从官方网站下…

    编程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用于Linux操作系统的一款照片管理器,它支持多种相机及存储设备,并提供了一系列强大的工具,让用户可以方便地浏览、管理、编辑和导出照片。本文将从多个方面对GTKAM进行…

    编程 2025-04-27
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • Linux网络连接激活失败原因及解决方法

    一、网卡驱动问题 1、缺少网卡驱动 若使用新的网卡,需要安装对应网卡驱动,否则会导致网络连接激活失败。可通过以下命令查看当前系统中是否存在网卡驱动: lsmod | grep et…

    编程 2025-04-25
  • 如何在Windows/Linux/MacOS下安装Python

    如果你对Python安装一无所知,本文将从多个方面对Python在Windows/Linux/MacOS下的安装做出详细阐述,为初学者提供帮助。 一、Windows下Python的…

    编程 2025-04-25
  • Linux Redis 重启

    一、概述 Redis 是一款高性能的 NoSQL 数据库,常用于各种应用场景的数据缓存、消息队列、实时数据分析等等。在使用 Redis 过程中,如果出现了某些问题,有时候只需要重启…

    编程 2025-04-25
  • Linux防火墙配置详解

    一、iptables基本介绍 iptables是一个重要的Linux内核中网络安全系统,通过设置iptables规则,可以对进入和离开Linux服务器的数据进行过滤。 iptabl…

    编程 2025-04-25

发表回复

登录后才能评论