Page 465 - 《软件学报》2025年第5期
P. 465
苏浩然 等: SPARC 架构下低时延微内核进程间通信设计 2365
一放置在单独的内核代码中并在内核特权级下运行的设计有所不同. 在宏内核架构下, 与操作系统功能相关的所
有函数都被统一放置在单独的内核代码中, 在内核特权级下运行. 因此宏内核架构常常会带来可靠性和安全性问
题, 比如当内核中的一个功能出错误或者遭到攻击时, 就可能导致整个系统崩溃或被攻击者完全掌控. 而微内核中
仅保留内存管理、线程调度、进程间通信等最基本的功能, 普通的用户态应用可以通过内核提供的进程间通信功
能使用用户态的系统服务, 以此提供较强的可靠性与易演化性.
微内核的可靠性和安全性也伴随着性能上的问题. 由于微内核中各种关键的系统服务和驱动都被视为一个用
户进程, 因此其他应用程序在需要使用这些系统服务时, 就不得不通过进程间通信 (IPC) 来进行. 而进程间通信会
导致进出内核以及上下文切换, 这两者都会带来额外开销, 而宏内核架构下仅需进出内核即可完成应用程序的请
求. 此外, 微内核中应用程序的一个请求可能会涉及多个系统服务, 而这些系统服务很可能是作为不同的进程运行
的, 因此在完成这一请求的过程中就可能发生多次 IPC, 带来明显的性能下降. 因此 IPC 的性能始终是微内核性能
的瓶颈之一. 这一现象自初代微内核 Mach [40] 问世时就被发现, 以 L4 [34] 为代表的第 2 代微内核对 IPC 进行了优化,
大幅提升了 IPC 性能, 并以此为基础衍生出了诸如 Pistachio, Fiasco 等微内核, 庞大的 L4 微内核家族在学术和工
业界被广泛应用 [41] . seL4 微内核 [33] 为 IPC 引入了能力 (Capability) 机制, 它使用能力表示用户程序对系统资源的
使用权限, 由内核负责管理, 并可通过 IPC 在不同进程间传输这一权限, 从而可以防止用户程序滥用系统服务, 进
一步提升了微内核的安全可靠性.
在微内核几十年的发展过程中, 有许多工作 [24−35] 都针对微内核的 IPC 性能进行了优化. 近年来, 一些工作着
眼于利用硬件特性进一步提升 IPC 性能. 比如 SkyBridge [25] 利用了 Intel 处理器的 vmfunc 特性, UnderBridge [35] 则
利用了 Intel 处理器的 MPK 特性. 然而这些优化工作只能在特定的处理器上使用, 对于目前在日常中比较少见但
在航天领域广泛使用的 SPARC 架构, 则鲜有相关研究.
2 研究动机
2.1 SPARC 架构寄存器窗口的开销
在 SPARC 架构提出之时, 函数调用的性能开销确实是应用程序性能的瓶颈之一, 因此寄存器窗口的设计能
够有效提升 SPARC 架构下寄存器的性能. 但是随着时代的发展, 函数调用时访存带来的性能开销逐渐下降, 应用
程序的主要性能开销之一在于进出内核. 进出内核时大多数情况下需要对应用程序的上下文进行保存, 而对于
SPARC 架构而言, 其所有寄存器窗口都需要被保存. 由于 SPARC 架构寄存器数量太多 (如果有 8 个寄存器窗口,
就有共计 136 个通用寄存器), 并且遍历时还需要对窗口进行滑动, 于是保存、恢复用户程序上下文的开销就被进
一步放大了. 我们在自研微内核 ChCore 上测试了 SPARC 架构上单次 IPC 的时延分布, 并排除了 IPC 服务端处理
请求的耗时, 结果如表 1 所示, 可见 IPC 中保存与恢复上下文的耗时就占了 IPC 总时延的 50% 以上, 对 IPC 性能
影响十分严重. 对于微内核而言, 由于 IPC 的广泛使用, 进出内核发生得更为频繁, 进一步限制了应用程序的性能.
表 1 SPARC 上 IPC 时延分布
操作 占比 (%)
上下文保存与恢复 57.0
进程切换与IPC处理 37.2
其他 5.8
我们对比了在 SPARC 架构上, 应用程序全程仅使用一个寄存器窗口以及使用全部寄存器窗口的性能. 为了
使应用程序全程仅使用一个寄存器窗口, 在对其进行编译时开启了编译器的-mflat 选项, 这一选项使得编译器像
其他架构那样在函数调用时使用栈保存寄存器, 并且不会生成滑动窗口的指令. 我们首先在 Linux 上测试了
nbench 中各程序的性能, 结果如图 2 所示, nbench 会运行一系列有代表性的算法测试程序并测量其吞吐量, 大多
数应用程序在仅使用一个寄存器窗口时, 性能下降不是很明显或几乎没有, 都在 2% 以内, 对于某些函数调用频繁
的应用, 性能下降也均在 10% 以内.