User Interrupt | My Note

User Interrupt

Updated: Sep 21st, 2023


用户态中断(User Interrupt)指的是能够在用户态注册中断处理函数,并且也能够在用户态触发指定的中断处理函数。这种功能可以通过很多种软件机制来实现,并用于进程间通信,在第四代至强 Sapphire Rapids 中,Intel 使用硬件实现了用户态中断,从而基于此实现了极低延迟的进程间通信。

背景:

背景1:硬件中断与 I/O

硬件中断

背景2:进程间通信

在并发编程中,我们常常遇到这样的场景:进程1需要等待进程2完成某事的标志,此时进程1可以选择轮询,也可以选择休眠,等待进程2完成后提醒进程1(类似软件中断)。

轮询需要消耗大量的CPU时间做无用的工作,延时最低,而软件实现的中断机制往往延时较大(依赖调度器的实现),不过由于等待通知的进程可以休眠,相比起轮询可以节省大量的CPU时间。

背景的总结

在计算机系统中实现“通知”这个功能,有很多种方法。

  1. 硬件实现的中断:只能在内核态触发和处理
    1. 引入了用户态内核态切换的开销以及内核其他软件栈的负担。
    2. 延迟最小!也不耗费额外CPU资源
  2. 软件轮询:可以在用户态触发处理
    1. 延迟较小
    2. 浪费大量CPU资源
  3. 软件实现中断机制:可以在用户态触发处理
    1. 延迟较大
    2. 不浪费CPU资源

看起来三种实现都有各自的弊端,没有哪一种是最好的。 但我们不妨想象一下,如果硬件实现的中断可以在用户态触发和处理呢?

硬件实现的用户态中断

Intel 官方文档中,详细介绍了第四代至强中新增加的 User Interrupts 指令集。另外 Linux 内核开发者也为此开发了一套基础接口,并在LPC2021上进行了相关的演讲

User Interrupts 指令集包含以下几个指令。

senduipi <uipi_handle> 
    – send a user IPI to a target task based on the UITT index.
uiret
    – Return from a User Interrupt handler  
clui
    – Mask user interrupts by clearing UIF (User Interrupt Flag).  
stui 
    – Unmask user interrupts by setting UIF.  
testui 
    – Test current value of UIF

#QUESTION : 硬件是如何实现这些用户态中断?

性能表现

Intel 基于 User Interrupt ,在ipc-bench的基础上开发了一个ping-pong IPC benchmark uintr-ipc-bench,并测试了一次ping-pong的延迟。

在下图中展示了用户态中断(User IPI)的延迟表现,该图中仅有一个相对性能。

no title picture

我运行了简单的几次测试,看起来一般的进程间通信(涉及内核)的方法需要 1~5 us 左右。如果按照上图所示的性能提升,那么这种用户态中断的延迟应该可以降低至几百ns 。

[wyf@cn3 signal]$ ./signal -s 1 -c 1000000

============ RESULTS ================
Message size:       1
Message count:      1000000
Total duration:     3566.216    ms
Average duration:   3.541       us
Minimum duration:   2.304       us
Maximum duration:   79.872      us
Standard deviation: 0.950       us
Message rate:       280409      msg/s
=====================================

[wyf@cn3 pipe]$ ./pipe -s 1 -c 1000000
============ RESULTS ================
Message size: 1
Message count: 1000000
Total duration: 6607.303 ms
Average duration: 6.582 us
Minimum duration: 5.376 us
Maximum duration: 84.224 us
Standard deviation: 0.631 us
Message rate: 151347 msg/s
=====================================

[wyf@cn3 eventfd]$ ./eventfd-bi -c 1000000 -s 1

============ RESULTS ================
Message size:       1
Message count:      1000000
Total duration:     7288.155    ms
Average duration:   7.263       us
Minimum duration:   1.280       us
Maximum duration:   1023.488    us
Standard deviation: 4.361       us
Message rate:       137208      msg/s
=====================================

用处,前景

我认为用户态中断最有用的场景应该是在:对各种高性能的硬件实现用户态的驱动。众所周知,高性能SSD、网卡早已面世,而为了压榨这些硬件的性能,必须要旁路内核,减少内核带来的额外开销。因此,各家厂商的驱动早就已经尝试实现各种优化,如网卡中的RDMA,SSD上的spdk框架,但由于硬件中断必须在内核中处理,因此无论是哪家的硬件都必须在内核中植入一个自己的驱动模块。如今用户态中断的出现,让未来有希望能够完全在用户态实现硬件驱动程序。

更近一步来说,如今Linux内核确实有些臃肿不堪,但其大部分的代码都是各种各种的硬件驱动,若以后硬件驱动可以在用户态中处理,Linux内核的代码规模是不是可以大大削减?是否以后可以让Linux走向更优雅的微内核(或混合内存)?

参考资料

  1. User Interrupts –A faster way to signal
    1. https://lpc.events/event/11/contributions/985/attachments/756/1417/User_Interrupts_LPC_2021.pdf
  2. 中断的本质是什么?
  3. 硬中断
  4. https://www.phoronix.com/scan.php?page=news_item&px=Linux-RFC-x86-User-Interrupts
  5. https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
  6. Linux Support For Sapphire Rapids’ User Interrupts Still Awaiting Mainline - Phoronix

Instead of authenticating the giscus application, you can also comment directly on GitHub.


Notes mentioning this note