硬件加速页迁移过程¶
标题:고려대학교 안정섭 교수, Accelerating Page Migrations
日期:2025/03/26
作者:안정섭
链接:https://www.youtube.com/watch?v=9zh91mIZ1_E
注意:此为 AI 翻译生成 的中文转录稿,详细说明请参阅仓库中的 README 文件。
备注:不给 demo,看下就好。(后来在 github 找到了,但是没有单独 commit)
嗯,过去通过提高ILP(指令级并行)显著提升了性能,但如今那样的时代已经结束了。我认为趋势正在转变为:添加某种功能,然后很好地利用该功能来使用。那么,这个数据流加速器(data streaming accelerator)的想法是,不使用CPU的加载存储(load-store)指令来处理数据复制中产生的问题,而是使用独立的硬件、即芯片内独立的加速器来处理。实际上,这并不是为了操作系统的某个特定功能而出现的。只是说,现在普遍地,这些情况需要大量数据,并且随着内存增大,数据来回移动、比较、清零等操作中产生的CPU周期,我们希望通过减少这些周期,让CPU真正专注于应用程序的周期,而其余那些工作呢,可以说是“由我们(加速器)来单独处理”的方式。是的。所以,我们本着“将数据流加速器中负责数据复制的那个东西,应用到内核中负责移动数据的那个部分上”的意图,开始了这项研究。
原本呢,正如前面郑镇圭教授所说,运行应用程序进行性能分析,从中找出瓶颈,然后一步步解决,这可以说是非常理想的路径。但我们呢,是反其道而行之。啊,既然有这个东西(加速器),那看看用它在哪里能更好呢?这样看就可以了。这里呢,嗯,其实大家大部分可能都知道,在数据中心等地方,实际上不仅有应用程序周期,还有其他方面,比如数据中心开销或者系统开销。数据中心开销的情况,比如管理VM或容器等管理层面的开销;系统开销则是诸如复制内存、分配等,就是刚才提到的那些系统内核最终使用的东西所花费的时间。实际上,CPU周期最好是最大限度地被应用程序用来运行应用程序,但现实并非如此。嗯,上面这个(指幻灯片)是ISCA会议上发表的论文,具体是哪个数据中心的我现在记不太清了。下面这个是Meta在他们自己的集群上做实验的结果,最终显示那里大约37%的开销是内存相关的开销。我们一直在进行并发表这样的讨论,已经相当久了。
所以,最近在英特尔处理器上可以看到,实际上我读学位时主要研究架构,并专注于研究为了架构、为了虚拟化或云计算能做些什么,因此对这些架构中加入的功能比较关注。其中,最近有被称为DSA(Data Streaming Accelerator)的,还有除了这个之外,被称为IA(In-Memory Analytics)的内存分析相关加速器也在不断添加。因为提高CPU性能存在极限,所以现在开始往里面塞各种东西(加速器)。我们呢,将焦点放在了其中这个叫DSA的东西上。最初注意到它的契机是,我们在研究大规模内存系统中的内存分层时,在查看那边内存相关操作中有哪些可以加速的过程中,就这样连接起来了。
嗯,正如刚才所说,利用这些功能,在应用程序层面直接使用它们的英特尔库等已经大量存在,应用程序也在展示如何使用它们。但是,操作系统并没有很好地利用这些功能。与其说有什么特别的原因,不如说可能只是因为工程实现上的问题吧。而且,并非所有处理器都是英特尔,所有系统也并非都基于英特尔处理器。但我们是研究者的立场,我们思考的是:能否很好地利用这些来优化性能?所以,我们开始研究如何在OS中应用这些内存操作,最终聚焦在最基本的内存复制操作上。那么,最终,内核中哪些组件能很好地使用这种内存复制呢?我们思考后,因为这是我们熟悉的领域,在页面来回移动的情况下,会大量使用内存复制。所以,在Linux中,几乎所有以页面为单位进行移动的操作,最终都归结到migrate_pages
(迁移页面)。啊,那么优化这部分就可以了。我们是这样想的。
但是,现在这个(加速)在应用程序层面或内核层面是如何被利用的呢?我们观察了一些内容。嗯,比如上午也提到过的kswapd
(回收内存)或kcompactd
(内存压缩),或者为了NUMA平衡在NUMA节点间来回移动数据,或者内存热插拔,或者像damon
(一个内存监控工具)这样的工具中,以页面为单位来回移动页面,执行大量这类操作。啊,那么如果我们优化migrate_pages
、对它进行加速,那些使用它、大量利用它的应用程序或情境,性能不就能提升了吗?这就是我们研究的方法。所以,这些(组件)最终会对系统产生很大影响,并且与资源管理密切相关。然后,我们判断,在像HPC或大规模应用这样最终大量使用内存的应用程序中,最终也会产生影响。
但是,这个DSA在机制上最终是:有硬件,将其暴露给软件的方法,其实和编程任何加速器的方法几乎相似。这里呢,创建一个叫做DSA描述符的东西,在里面指定要复制哪里的内存、从哪里复制到哪里等等,然后直接扔到这个DSA硬件队列里。如果队列里有工作项,就会有引擎运行,一个个地调度出来执行任务。这里可以看到,这些任务可以异步执行,也可以同步执行,有这些方法。嗯,这些其实都是细节内容。所以,因为要复制数据,所以需要有源地址和目标地址,当这些地址分散在多处时,必须以分散-聚集的形式处理,因此需要创建这样的表。这些地址需要转换成支持DMA的IO虚拟地址,然后将它们制作成描述符扔过去。扔过去之后,期间CPU实际上可以做其他事情。从加速器的立场来看,正如刚才所说,就是“这些事由别人做,我的周期用来运行应用程序”。然后,结束后,通过接收中断来处理剩余工作,主要就是这样利用的。
性能上有些差异。所以,这个DSA呢,其实…,英特尔以前也有能做类似事情的…,有那样的加速器。编程方法和那个有些不同,不过编程方法本身似乎意义不大,性能有些不同,在CPU空闲方面,似乎能更好地利用CPU。DMA也是英特尔的吧?啊,是的是的是的。但是,具体是什么样的性能差异,哪个部分导致性能提升的,我们没能确切掌握。不过之前有利用之前加速器的研究存在。关于这个我有个疑问:这个IOH系统DMA,比如,是PCI设备对CPU内存之类的做内存复制吧?是的是的是的。这个也能做内存到内存,但其他内存,设备内存。那个我们没试过,如果内存映射了应该可以,但其他的可能需要尝试才知道,我们没试过。
提问: DSA在用户空间也能用吗?
回答: 是的。原本至今的开发都是为了让用户空间也能使用。所以有开源库之类的,例如为了让数据库等能使用,DSA或IAA之类的库已经开发了很多。是英特尔开发的。但是,据我所知,内核中尝试使用这些的还不多。
提问: 那么,在上下文切换时,那不是需要可冻结的上下文吗?
回答: 不是那样的。不是那种。用户在用着然后突然冻结… 用户在用DSA时…
回答: 那个我们稍后后面会讨论,但那个目前没有考虑。就是说,至今为止设定是用户只用用户的,我们这里呢,是只让内核用。我们等同地只让内核一个实体使用,就是只能这样用。嗯。现在是那样做的。
回答: 但是我们实验过。如果让一个用户也用我也用,就会发生双方都非常不愉快的情况。最终,以后OS需要提供这种硬件抽象?不能只让内核用,用户也需要用。那么,用户应用程序可能有多个,内核也可能在多个地方需要使用这种加速器。OS如何提供抽象、如何管理,这实际上可能成为更根本的设计研究。
提问: 如果有两个插槽呢?
回答: 嗯。那么各自用一个一个… 啊,这个结构我还没详细讲。DSA这个东西很特别,英特尔可能大家听说过,它是以“按需”之类的产品名销售的。“按需”的意思是一开始买CPU时就是按需购买。从他们的立场看,买的时候多付钱,就可以最多暴露4个DSA给你。不付钱,那就只有一个。不过那一个里面又有多个处理引擎。所以这个结构是,CPU里面可能每个插槽有一个,也可能每个插槽有四个,或者两个,那两个里面又用多个引擎,可以完全进行某种程度的扩展。如果同时使用,最终会相互争用…
提问: 是的。
回答: 对。所以如果共享处理引擎使用,就会发生争用,对双方都不好。所以,如何管理这些并提供抽象,实际上我们现在讨论在OS中使用这些东西,当然应用程序想使用的目的会更多,并且可能发生争用,所以是严格分区使用,还是动态管理使用,当有多个这样的加速器时,嗯,这里说的加速器不是GPU。GPU现在完全在OS之外。OS一点角色也做不了。不过除了那些,对于这种数据中心或系统级管理操作进行协处理的加速器,我们对OS设计该如何做比较感兴趣。
提问: 不太确定,这个有SoC依赖的问题吗?SoC依赖是说必须在CPU内部吗?还是外部也可以?
回答: 首先是在CPU芯片内部。但不是在芯片里像代码那样,这个实现本身,实际上这个加速器看起来像是通过PCI连接的加速器。
提问: IP可以拿出来吗?
回答: 嗯。据我所知目前只有英特尔产品。所以我们先上传了,测量了卸载后能加速多少。X轴是4KB迁移页面,所以是从16个4KB页面单位增加到510个。左边是只用CPU进行memcpy
的情况,右边是使用DSA进行memcpy
的情况。这个细分包含了使用DSA带来的各种中间设置等成本。所以,我们… 这个在DSA的白皮书之类的地方也提到过,一个一个地处理4KB页面是没有意义的。因为开销太大了。所以根据我们的实验来看,啊,从32个开始才有意义。“有意义”是指性能虽然差不多,但CPU可以做其他事,所以算有意义。从批量处理64个页面开始,性能差距就出现了,报告认为有理由使用它,我们通过性能分析得到了这个结果。啊,那么内核中一个一个地移动页面其实是最常见的,事实上还有更小的、比页面单位更小的memcpy
情况,比如设备驱动等,但在那些情况下使用这个其实比较困难。所以我们刚才实际上在这里稍微提到的,就是找到了这些。虽然是以更大的单位、页面单位移动,但针对“有哪些移动页面集合的情况”我们做了很多思考。所以,我们认为加速这类操作,可以给内核带来帮助。
所以我们迄今为止尝试的方法非常简单。虽然不能说实现起来非常容易,但我们首先简单地实现为:当移动超过32个页面的情况,就走向我们实现的DSA逻辑;否则,就回退到原有的方法。
我们在实现这个时,实际上,在它工作期间CPU周期是空闲出来的,所以我们期望一个美好的图景:CPU应用程序能更好地推进,从而带来性能提升。但那个美好的图景并没有很好地出现。所以,我们打算展示使用轮询技术的方式。我们的实验… 如果做4个价格也会上涨很多。所以这是在有两个CPU芯片的服务器上,每个插槽有一个DSA。不过我们只在单插槽上进行,128GB内存这样的环境。我们主要关注两个方面:kcompactd
和基于damon
的情况,它们都涉及大量页面同时移动的情况,kcompactd
也有这种情况,所以我们选择了这两个。
所以,压缩内存的kcompactd
,就像之前提到的kswapd
运行方式类似,有某种阈值,有一个表示碎片化分数的指标在内核里。那个分数在这里是90这个数字,达到后它就激活了,开始对碎片化的东西进行压缩。所以,这个是我们运行某种工作负载时做的。两个方向,使用两种CPU和使用DSA时。X轴是时间,随着时间推移,碎片化分数很高,所以触发了压缩。然后随着压缩,观察碎片化分数下降的速度。结果是使用DSA比使用CPU时下降得更快一些。右边显示的是每秒这个“主动压缩节点”的功能,DSA能执行多快,测量了这些。从吞吐量看,观察到DSA能处理得更高一些。
然后,嗯… 我们瞄准了damon
。我们之前就在做与内存分层相关的研究,所以一直在看damon
。简单介绍一下damon
:它监控非常大的内存空间。那么,它开始以比页面大得多的单位“区域”进行管理,我们称之为区域。所以按区域执行某些操作。按区域决定是否交换、是否提升、是否降级。因此,一个区域里就有一组页面。啊,所以像damon
这样的情况,DSA有大量机会加速32个以上的页面操作。所以我们在这个damon
daemon中… 实际实验时,最初实验是使用HM SDK,针对类似CXL的第二层内存中的数据需要移动到DRAM的这种用例进行实验。这个HM SDK已经合并到了damon
里。所以它里面包含了这个。我们没有CXL设备,所以通过调节远程插槽的非核心频率来制造较慢的内存进行实验。实验做的是内存提升。我们做的是… 那个名字叫什么来着?Gap Benchmark或者XS Benchmark的SSSP图分析基准测试。这个XS基准测试有点像机器学习内核。做这些测试时,快速层的所有数据都在DRAM上,慢速层都在类似CXL的地方,数据分配在那里。有使用CPU的damon
,也有用DSA加速的damon
。这个CPU或DSA探测到分配在慢速层的数据… 所以这个其实也取决于damon
的能力… 通过这个进行提升的结果显示在这里。这个是标准化执行时间,快速层是1,所以越接近1性能越好。使用DSA能获得更快的结果。右边可以看到,和前面一样,最终每秒移动了多少页面,可以看出能移动更多得多的页面,因此我们得到了这些结果。
我们还对页面大小等做了实验。有4KB页面和2MB页面,在2MB页面上,明显观察到DSA的效果更好得多。刚才有很多提问交流,但最终,这个东西原本用途并非固定死的,用户可能想用,用户的应用程序可能想大量批量使用,我们在内核中也在各处寻找,但认为它可以在多个地方被利用,所以尝试了共享它。“共享”是指… 非共享是指用户和内核线程使用完全分区的独立硬件。共享是指用户和内核线程共享一个处理引擎的情况。我们人为制造了这种共享情境进行实验。结果发现,如果共享,比起非共享的情况,速度明显慢很多。我们观察到,甚至比共享还不如直接用CPU更好。这一点我们通过实验确认了。
所以,嗯,好像很快就讲完了。我们迄今为止做的是,这项研究发表在IEEE Computer Architecture Letters这个大约四页的期刊上,是提交发表的内容。我们最终打算扩展它。所以我们在寻找我们看到的migrate_pages
的应用范围,或者虽然不以页面为单位移动,但DSA可以加速的其他地方有什么机会。比如存储或网络。例如,我们现在在看的是,说是存储,像页缓存,把数据放在页缓存上,然后用户从这里取走的场景,如果用DSA来取,应该会好很多。我们正在评估这类事情。然后,更进一步,最终这不仅仅是开发完就结束了。学术上,如果只是说“用了DSA加速了”,现在人们会说“哦,辛苦了,结束了”。而思考“这能带来什么启示”时,考虑到这类会大量出现,那么OS该如何对它们进行多路复用?OS的工作就是多路复用、隔离和抽象。我们正在思考,对于这类硬件,OS如何能做到这些?嗯,我准备的内容就到这里。如果还有好奇的部分,嗯,在我知道的范围内我会回答,不知道的我会通过学生来回答。谢谢大家。