LWN:对NUMA更加优化的qspinlock!

libnuma详解(A NUMA API for LINUX) 白皮书 numa3手册 numa3手册 一、什么是NUMA 关于这个很多博客都有,基本都是这个白皮书的翻译或者扩充。 在传统的SMP(对称多处理)系统中,计算机有一个由所有cpu共享的内存控制器。当所有处理器同时访问内存时,这种单一内存连接常常成为瓶颈。对于具有更多cpu的大型系统,它也不能很好地扩展。由于这个原因,越来越多的现代系统正在使用CC/NUMA(缓存一致性/非一致性内存访问)架构。例如AMD* Opteron*、IBM* Power5*、HP* Superdome和SGI* Altix*。 阅读详情

关注了就能看到更多这么棒的文章哦~

NUMA-aware qspinlocks

By Jonathan Corbet
April 12, 2021
DeepL assisted translation
https://lwn.net/Articles/852138/

虽然 core kernel (核心部分的内核代码)中有些部分在几年前就达到了相对稳定的 "done"状态,但其他部分似乎距离完工还差很远。这部分有一个很好的例子,就是是内核中 spinlock 的实现。spinlock 在内核的底层来对数据访问进行仲裁。这类锁的性能表现对整个系统的性能有很大的影响,所以对其进行的优化工作可以得到很大好处。为了避免让人们认为这项工作已经完成,最近又出现了一个 NUMA-aware qspinlock patch set,展示了如何从内核的 spinlock 实现中继续提高性能。

之前用最简单的方式来实现的时候,spinlock 是内存中的一个 word,初始值为 1。任何希望获得锁的 CPU 都会执行一个原子操作 decrement-and-test(递减并判断),如果结果为 0,则说明成功获得这个锁。否则的话 CPU 需要在对这个值进行递增操作,接下来一直在这个小循环中 "spin(旋转)",直到操作成功为止。内核早已抛弃了这种实现方式,原因有很多,性能就是其中之一。所有这些对 lock word 的原子操作都会导致 cache line 会在系统中(也就是多个 CPU 上)来回跳,哪怕这个锁的竞争并不激烈,cache line 的变化也会大大降低系统速度。

目前的 "qspinlock "实现是基于 MCS lock 的,它会将所有在等待这个锁的 CPU 排成队(queue),用链表来管理。一般来说,当人们担心 cache 的效率时,一般都会希望避免使用链表这种数据结构,但在这个场景中其实任何一方都不需要遍历这个链表。相反,每个 CPU 都只会在链表中跟自己有关的这一项上进行 spin 等待,并且只有在释放 lock 的时候才会走到下一项。关于 MCS 锁是如何工作更完整的描述,请看这篇文章,其中有一些通俗的示意图。

MCS locks on NUMA systems

MCS 锁看起来几乎是效率最高的方案了。每个 CPU 都只关注队列中自己这一项就好,所以处理器之间的 cache-line 跳来跳去的操作几乎完全被消除了。它们也保证了公平性,这个排队队列确保了没有一个 CPU 会过长时间拿不到访问权。但现在看来还有改进余地,至少在非一致性内存访问(NUMA,non-uniform memory-access)系统上是这样的。这种系统包含多个节点(node),每个节点包含若干 CPU,访问那些连接到本 CPU 节点的内存,比起连接到其他节点的内存速度更快。当然,无论内存连接在哪个节点上,对 cache 的访问都是(相对)最快的,但是在节点之间移动 cache line 的动作开销很大,甚至比在同一节点上的 CPU 之间发生 cache line 来回跳动的情况性能还要更加差。因此,需要尽量减少 NUMA 节点之间的 cache line 移动,从而改善性能。

如果某个 spinlock 被一个节点上的 CPU 释放了,随后被另一个节点上的 CPU 获得,那么它的 cache line 将不得不在两个节点之间移动了。相反,如果一个 spinlock 可以被传递给同一节点上的另一个 CPU,就没有这个昂贵的开销了。仅仅这一点区别就会已经会引入性能差异了,但不仅如此,别忘了 spinlock 是用来保护数据结构的。两个 CPU 在争夺某个锁的时候很可能是希望访问同一个数据,所以在节点之间移动这个锁也很可能意味着受保护的数据所在的 cache line 也会发生移动。对于竞争很严重的数据结构来说,由此带来的速度下降会很严重。

NUMA-awared qspinlock 会尽可能地将锁移交给同一节点上的另一个 CPU,来防止锁在 NUMA 节点之间来回移动。要做到这一点,那么管理这些等待锁的 CPU 的队列被分成了两个——主队列(primary)和次要队列(secondary queue)。如果一个 CPU 发现暂时抢不到锁,它会把自己加入主队列,像往常一样等待。不过,当一个 CPU 到了队列的最前端的时候,会看一下排在后面的 CPU,如果下一个 CPU 属于另一个 NUMA 节点,就会把下一个 CPU 分流到次要队列中。

这样一来,在等待的 CPU 都会被分到两个队列中去,其中一个队列(主队列)只包括与当前锁的主人在同一节点上的那些 CPU,另一个队列(次要队列)则包含所有其他的 CPU。当某个 CPU 释放锁时,会将锁交给主队列中的下一个 CPU,从而将锁保持在同一个 NUMA 节点上。只有当主队列清空时,锁才会移到另一个节点上,这时,次要队列就会变成主队列,这个过程又重新开始。

Tweaks and benchmarks

这个方案有一个明显的隐患:如果锁的竞争非常激烈,那么主队列可能永远不会清空,系统中的其他节点就会长时间拿不到锁。解决这个问题的办法是记下首次将 CPU 移到次要队列的时间。如果主队列在 10ms (缺省设置)后仍没有清空,整个次要队列将被插入到主队列的头部,从而迫使这个锁被转移到其他节点。可以用 numa_spinlock_threshold 这个 cmdline 参数来改变超时时间(在 1-100ms 的范围内)。

已经添加了一个名为 "减少洗牌(shuffle reduction)" 的优化。如果锁的争夺不是那么激烈,那么维护次要队列的这些额外工作并没有真正带来什么好处。为了减少这种额外的成本,代码使用了一个伪随机数生成器,每 128 个锁的获取中只会尝试创建一个次要队列。如果锁变得繁忙起来,这个操作会更加频繁地发生,此后就会一直维护这些次要队列,直到主队列再次被清空(或发生上面提到的超时事件)。

最后要讲的是,运行在中断模式(或不可屏蔽的中断,non-maskable interrupt)下的 CPU,以及运行实时任务的 CPU,都不会被移动到次要队列中。这使得这些 CPU(它们可能具有更高的优先级)能够相对快速地获得锁,尽管它们运行在不是最优的 NUMA 节点上。

patch set 中包含了一些基准测试数据。对于轻度竞争的锁来说,这个新的方案带来的性能优势相对较小。不过,随着竞争线程数量的增加,性能优势也在增加,对于严重竞争的工作场景,速度提升接近 2 倍。

这组 patch set 自 2019 年 1 月首次发布以来,已经经历了 14 次修订。这段时间里随着 review 意见的不断提出和解决,已经有了相当大的发展,目前似乎正在接近稳定状态,可能快要被合并了。不过,鉴于这项工作已经被审查了两年多了,而且它对内核的最基本的同步元语(synchronization primitive)之一进行了重大的修改,所以也仍然有可能会需要更长的时间才能合入 mainline。

这篇论文 对 NUMA-aware qspinlock 算法的细节进行了更多介绍,不过目前最新实现代码的细节与 f 论文所描述的会有一定的出入。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

PV qspinlock原理 1 前言 自旋锁(spinlock)是用来在多处理器环境中工作的一种锁。如果内核控制路径发现spinlock是unlock,就获取锁并继续执行;相反,如果内核控制路径发现锁由运行在另一个CPU上的内核控制路径lock,就在周围“旋转”,反复执行一条紧凑的循环指令,直到锁被释放。spinlock的循环指令表示“忙等”:即使等待的内核控制路径无事可做(除了浪费时间),它也在CPU上保持运行。 spinlock的实现依赖这样一个假设:锁的持有线程和等待线程都不能被抢占。但是在虚拟化场景下,vCPU可能在任意时刻 阅读详情

相关推荐

NUMA架构下的内存分配策略

NUMA下的内存分配策略 通常的内存分配策略我们已经有所了解了。UMA是统一内存访问,无论任何 CPU 执行操作,访问时间都相等。而NUMA是非统一内存访问,在不同的节点的访问速度不一样,离本地越远访问越慢。在NUMA上我们有不只一个节点,我们可以在不同的节点上分配内存。 内存分配和策略 通常NUMA下的内存分配有显式和隐式两种。 显式分配 显式分配即指定节点的分配函数,此类基础分配函数主要有2个:Buddy系统的 alloc_pages_node()和SLAB系统的kmem_cache_alloc_nod

weixin_48101150的博客 3233

关于多核 CPU 自旋锁 (spinlock) 的优化

CPU的总线为铜薄膜,虽然摩尔定律使单位面积晶体管的密度不断增加,但是对于连接导线的电阻却没有明显的下降,导线的RC延迟几乎决定现有CPU性能,因此我们会看到传输数据在CPU的角度来看是个极为沉重的负担。我们看到intel 为了引入更多的CPU核心,从Skylake开始芯片总线由上一代的 ring-bus 转变为 2D-mesh, 虽然2D-mesh为数...

测试0901-1 2953

trae CN 配置ida的mcp教程

本文介绍了在TraeCN中配置IDA Pro MCP服务的完整步骤:1)准备IDA Pro 9.0+和Python 3.11+环境;2)安装MCP服务端并配置插件;3)生成MCP配置文件;4)在TraeCN中添加HTTP类型MCP服务(默认端口13337);5)测试连接。重点说明了HTTP配置方式的操作流程,包括手动启动服务、正确填写JSON配置等关键环节。

2401_87915504的博客 1955

MOT的概念:NUMA-aware分配和亲和性

MOT有一个智能内存控制模块,它预先为各种类型的内存对象分配了内存池。这种智能内存控制可以提高性能,减少锁并保证稳定性。事务的内存对象分配始终是NUMA-local,从而保证了CPU内存访问的最佳性能,降低时延和争用。被释放的对象返回到内存池中。在事务期间最小化使用操作系统的malloc函数可以避免不必要的锁。

weixin_53596073的博客 620

DEAP数据集实战指南:从脑电信号到情绪分类的完整流程解析

本文提供了DEAP数据集在脑电信号情绪识别领域的完整实战指南。详细解析了数据下载、结构理解、频带功率特征提取等核心步骤,并演示了如何构建和评估机器学习分类模型,为研究者实现从原始脑电信号到情绪分类的完整流程提供了清晰路径。

jj890的博客 889

告别串口助手!手把手教你用Matlab直接读取STM32的传感器数据(附完整代码)

本文详细介绍了如何利用Matlab直接与STM32进行串口通信,实现传感器数据的实时采集与分析。通过完整的代码示例和系统架构设计,帮助开发者告别传统的串口助手工具链,打造高效、自动化的数据采集系统。文章涵盖了从硬件配置、通信协议设计到Matlab数据处理与可视化的全流程,特别适合嵌入式开发与数据分析结合的实践场景。

weixin_42629671的博客 428

linux系统下如何查看cpu能同时跑几个线程_探讨基于Linux的NUMA系统

相信我们从事IT基础设施开发的朋友们都听说过NUMA,以前自己也零零散散地听到过一些概念,还仍感不太系统,最近研究的基于scylla的DB时,就发生过内存回收compaction的问题。今日在几篇文章和论文的推动下,打算用此文将NUMA讲得全面一点,但也不会太底层,所以主打核心概念/设计思想,稍展开细节(展开多了感觉自己都成翻译员了 ~~~)。从处理器到内存间的电子信号速度决定了CPU访问内存的延...

weixin_39594895的博客 513

HLM(多层线性模型)在stata中语句

在阅读CEPS中发现有些研究采用的是HLM模型,HLM简单来说用一个方程跑两个回归。举例,对学习成绩影响因素,不同层有不同的影响,如在个体层面上个体特征会对成绩产生影响,在学校层面学校排名等因素会对成绩产生影响,两种因素不在一个层面,每层造成的差异都不相同。 在找相关语句时候发现操作这个语句的软件大多是SPSS和HLM,对于stata操作者并不友好。因此,在有限资料中总结了HLM在stata中的语句,后面会附上学习视频和链接。 先放语句,后面对方程式一个大致解析。由于针对HLM有一本书的介绍,可能一篇文章无

weixin_44652251的博客 1万+

鲲鹏HCIP练习01答案

收集热点函数工具:perf JVM屏蔽了x86与鲲鹏平台之间的差异 多核乱序指令现象 LDR,LDR Rt, 二进制:he11o.o 中断向量表 老年代存活对象大小为X。堆总的大小为3X-4X。 or运算:EOR Vd,Vn,Vm 鲲鹏处理器实现虚拟化的具体方式和x86处理器有区别。 如果一个超线程处理器可以让每个核执行两个线程,那么一个4核的处理器可同时并行执行8个线程。4*2=8 复制就是开销,在程序开发和设计阶段可以尽可能的避免此类开销。 有一个x86平台软件,它使用了Intrinsic指令,如果要在

slow的博客 3945

避坑指南:PVE下N卡直通错误代码43的终极解决思路与dmesg日志分析

本文详细解析了PVE环境下NVIDIA显卡直通时遇到的错误代码43问题,提供了从dmesg日志分析到BIOS配置、PVE宿主机优化及虚拟机设置的完整解决方案。特别针对GTX1060等显卡,分享了驱动版本选择、ROM修补及高级排错技巧,帮助用户彻底解决这一常见难题。

weixin_28693683的博客 287

ubuntu 18.04 + Kimera slam 安装与demo测试

环境:opencv 3.4.12,其他的都是按照文档下载的。 首先进行组件的安装 一、Kimera-VIO 安装参考文档:https://github.com/MIT-SPARK/Kimera-VIO/blob/master/docs/kimera_vio_install.md 按照文档装就好,在安装过程中碰到如下问题: 0、make 过程很卡,不要用所有的核 1、cmake过程中卡下载 ORBvoc.zip ,手动下载这个文件,解压,将里面的3个文件,放到/Kimera-VIO/vocabu.

dna葡萄糖的博客 3628

磐维数据库增量检查点和NUMA-AWARE原理

为了解决NUMA架构引起的资源消耗不均及跨Node之间访问资源延迟大的问题,面向Numa架构进行优化,其基本原理是:设置执行线程和Node/核心的亲和度,将线程保定在指定的CPU核心运行,避免进行跨Node调度,降低CPU上下文切换。同时,使用NUMA数据结构,实现数据异步拷贝。为了不全量回滚日志,引入了检查点。将当前位于内存中的事务日志持久化,将脏页持久化,记录Checkpoint日志,其中保存REDO点,每次再刷脏页就会从REDO点之后开始,但是如果遇到了脏页过多情况,则会出现写峰值的问题。

Wy1709945的博客 812

基于模型上下文协议(MCP)的可插拔式临床AI工具链Clinical DS研究(下)

本研究深入探讨了医疗AI在临床落地中的核心矛盾,即如何从“模型能答”迈向“系统可信、可用、可追溯”。为解决此矛盾,我们创新性地提出并详细设计实现了一套基于模型上下文协议(MCP)的**“可插拔式临床AI工具链”**架构。通过将复杂的医疗AI系统解构为Host、MCP Server和标准协议三层,并将各类能力(临床决策、影像分析、合规审计)封装为标准的、可独立演进的Server,我们成功地构建了一个模块化、高内聚、低耦合的系统。

AllenLV的博客 1380

NUMA架构的CPU -- 你真的用好了么?

本文从NUMA的介绍引出常见的NUMA使用中的陷阱,继而讨论对于NUMA系统的优化方法和一些值得关注的方向。 文章欢迎转载,但转载时请保留本段文字,并置于文章的顶部 作者:卢钧轶(cenalulu) 本文原文地址:http://cenalulu.github.io/linux/numa/ 本博客已经迁移至: http://cenalulu.github.io/ 为了更好的体验,请通过此链接...

weixin_30278237的博客 1946

“华为杯”研究生数学建模竞赛2020年-【华为杯】B题:汽油辛烷值优化建模(附优秀论文)

摘 要:本文通过机器学习算法和数据挖掘技术,建立了汽油辛烷值(RON)损失的预测模型,在保证汽油产品脱硫效果的前提下,以降低汽油辛烷值损失在30%以上为目标,给出每个样本的优化操作条件。针对第一问,对285号和313号原始数据用给定的数据处理规范进行预处理,对每一列变量求期望,得到最终的数据补充到相应的样本编号。针对第二问,首先对数据样本按照最大最小限幅以及拉依达法则进行列变量清洗,通过两轮特征筛选确定变量:结合处理后的数据,针对产品中硫含量、RON损失值用。

getusushu的博客 1251

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

细数6种垃圾回收器的区别, 快进来看看有没有你要用的

大家好啊, 这里是Yve菌, 今天给大家详细介绍一下我们在进行GC垃圾回收时的主力军-垃圾回收器. 由于我们使用的jdk版本有不同, 使用的堆内存大小也不同, 这个时候我们可能就会用到不同的垃圾回收器. 垃圾回收器目前来说在市面上会有很多, 今天我们就来详细讲讲以下垃圾收集器:我们了解到了这么多垃圾收集器, 那么我们怎么去选择使用呢?优先调整堆的大小让服务器自己来选择如果内存小于100M,使用串行收集器如果是单核,并且没有停顿时间的要求,串行或JVM自己选择。

Limelimelimes的博客 1142

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

linux内核级性能调优

linux 内核调优

zhangyihu321的专栏 1663

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

突破Windows内存瓶颈:WinFsp的NUMA-aware内存池技术解析

在多CPU服务器上部署文件系统时,你是否遇到过这些问题:明明内存充足却频繁出现分配失败?跨NUMA节点(Non-Uniform Memory Access,非统一内存访问)的内存调用导致性能骤降?WinFsp作为Windows平台领先的用户态文件系统框架,其内核模式驱动中的内存池设计为解决这些问题提供了创新方案。本文将深入解析WinFsp如何通过NUMA-aware内存分配策略,实现高性能、高可靠...

gitblog_00764的博客 876

UMA架构与NUMA架构下的自旋锁(CLH锁与MCS锁)

关于自旋锁我们知道自旋锁是实现同步的一种方案,它是一种非阻塞锁。它与常规锁的主要区别就在于获取锁失败后的处理方式不同,常规锁会将线程阻塞并在适当时唤醒它。而自旋锁的核心机...

远洋号 1696

Linux 的 Spinlock 在 MIPS 多核处理器中的设计与实现

引言 随着科技的发展,尤其是在嵌入式领域,高性能、低功耗的处理器成为众多厂商追逐的目标,但是由于技术和工艺的瓶颈,试图在单核处理器上达到这样的目标变得越发困难,于是人们提出了多核处理器的概念。多核处理器的核心思想是一个处理器中包含若干个核(或线程),所有核(或线程)之间共享 IO、Cache、内存等资源,对于这些资源的使用和分配由硬件来完成,用户无需关注细节,因此每个核(或线程)对于用...

dianshu1593的博客 216

Linux内核中的几种自旋锁的实现

queued spinlock

Hober 7188

Linux kernel 配置选项

General setup 常规设置 Cross-compiler tool prefix CONFIG_CROSS_COMPILE 交叉编译工具前缀(比如"arm-linux-"相当于使用"make CROSS_COMPILE=arm-linux-"进行编译).除非你想配置后默认自动进行交叉编译,否则不要使用此选项. Local version - append to kernel rel...

qq_28779021的博客 1万+

为什么 NUMA 会影响程序的延迟

NUMA对程序的延迟影响

johnhuster的专栏 1722

qspinlock 自旋锁的原理以及实现

文章目录qspin-lock的原理以及实现没啥用的前言介绍数据结构介绍锁结构CPU副本代码分析初始化加锁解锁与尝试解锁一些问题我们到底在等待什么? qspin-lock的原理以及实现  ticket spinlock已经有大量完善的分析文章,arm64 在kernel在4.16rc6之后就将默认的spinlock改为了qspinlock,目前分析的文章较少,并且看了下还是很难理解,我自己还是啃代码看完的,所以这里做个记录。 另外,还没遇到过qspinlock引起的问题,没看到运行时的相关数据结构,这篇文章只

feisezaiyue的博客 5001

FPGA乘法器实现方案对比:LUT、DSP与移位相加的选型指南

在数字电路与FPGA开发中,乘法器是实现数字信号处理、图像处理等算法的核心运算单元。其基本原理是将两个二进制数通过硬件电路进行相乘,产生乘积结果。从技术价值看,高效的乘法器设计直接决定了系统的性能、功耗和资源利用率。在应用场景上,不同的实现方案各有侧重:基于LUT的组合逻辑乘法器适合小位宽、非关键路径的快速原型验证;基于专用DSP Slice的乘法器凭借其高性能和低功耗,成为**DSP密集型应用**(如FIR滤波器、FFT)的首选;而基于移位相加的时序乘法器则以极低的资源消耗,在**资源极度紧张**或对延迟

weixin_33724659的博客 435

JVM垃圾算法与垃圾收集器

JVM垃圾收集算法 JVM垃圾收集器

paopaodog的博客 601
上一篇: LWN:对比 SystemTap 和 bpftrace!
下一篇: LWN:seccomp用户空间通知功能以及信号处理!
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值