【问题标题】:Use of floating point in the Linux kernelLinux内核中浮点的使用
【发布时间】:2012-12-02 21:45:32
【问题描述】:

我正在阅读 Robert Love 的“Linux Kernel Development”,我偶然发现了以下段落:

不(容易)使用浮点数

当用户空间进程使用浮点指令时,内核管理从整数到浮点模式的转换。内核在使用浮点指令时必须做的事情因架构而异,但内核通常会捕获一个陷阱,然后启动从整数模式到浮点模式的转换。

与用户空间不同,内核没有对浮点的无缝支持,因为它不能轻易地陷入困境。在内核中使用浮点需要手动保存和恢复浮点寄存器,以及其他可能的琐事。简短的回答是:不要这样做! 除了在极少数情况下,内核中没有浮点运算。

我从未听说过这些“整数”和“浮点”模式。它们到底是什么,为什么需要它们?这种区别是否存在于主流硬件架构(例如 x86)上,还是特定于一些更奇特的环境?从进程和内核的角度来看,从整数模式到浮点模式的转换究竟需要什么?

【问题讨论】:

  • 这本书通过谈论“模式”来混淆这个问题。整数指令始终可用,但 FPU 可以完全或部分禁用。从来没有一个有用的函数完全由 FP ops 组成,例如,所有的控制指令都被认为是“整数”。更多信息请参见下文。
  • @DigitalRoss:我同意这个术语。顺便说一句,感谢您的回答,这让事情变得一清二楚。
  • 了解在内核中进行浮点运算的愿望是从何而来的会很有趣。从试图在内核中做一些应该在内核之外做的事情的意义上说“糟糕的设计”是很诱人的,但也许内核真正应该做的事情是利用 FPU 是一种创新的解决方案?跨度>
  • 由于没有人提到它,如果你在内核中使用 FP(或 SIMD),你需要在你的代码之前/之后调用kernel_fpu_begin()/kernel_fpu_end()确保用户空间 FPU 状态没有损坏。这就是 Linux 的 md 代码对 RAID5 / RAID6 所做的。

标签: linux floating-point linux-kernel


【解决方案1】:

因为……

  • 许多程序不使用浮点或不在任何给定的时间片上使用它;
  • 保存 FPU 寄存器和其他 FPU 状态需要时间; 因此

...操作系统内核可能会简单地关闭 FPU。 Presto,无需保存和恢复状态,因此可以更快地进行上下文切换。 (这就是 mode 的意思,它只是表示启用了 FPU。)

如果程序尝试 FPU 操作,程序将陷入内核,内核将打开 FPU,恢复任何可能已经存在的已保存状态,然后返回以重新执行 FPU 操作。

在上下文切换时,它知道实际执行状态保存逻辑。 (然后它可能会再次关闭 FPU。)

顺便说一句,我认为这本书对内核(而不仅仅是 Linux)避免 FPU 操作的原因的解释......并不完全准确。1

内核可以陷入自身并在很多事情上这样做。 (定时器、页面错误、设备中断等。)真正的原因是内核并不特别需要 FPU 操作,并且还需要在根本没有 FPU 的架构上运行。因此,它只是避免了管理自己的 FPU 上下文所需的复杂性和运行时间,因为它不执行总是有其他软件解决方案的操作。

有趣的是,如果内核想要使用 FP ,则必须多久保存一次 FPU 状态。 . . 每个系统调用、每个中断、每个内核线程之间的切换。即使偶尔需要内核 FP,2 在软件中执行它可能会更快。


1. 也就是说,错了。
2. 我知道内核软件包含浮点算术实现的几个案例。 一些架构在硬件中实现了传统的 FPU 操作,但将一些复杂的 IEEE FP 操作留给了软件。 (想想:非正规算术。)当一些奇怪的 IEEE 极端情况发生时,它们会陷入软件,该软件包含可以陷阱的操作的迂腐正确仿真。

【讨论】:

  • 内核通常不会“关闭 FPU”。我什至不确定在当前的处理器型号上是否可行。相反,内核只是省略了为不使用它的进程保存和恢复 FPU 数据。如果进程 F 使用 FPU 一段时间,然后被中断或暂时停止,其他不使用 FPU 的进程可以来来去去。您不想为它们关闭 FPU,因为它仍然保存来自进程 F 的数据。内核只是让这些数据保持不动而不保存它......
  • ... 当进程 F 再次运行时,它可以继续使用 FPU,其数据已经存在。如果另一个想要使用 FPU 的进程运行,那么内核需要保存 F 的 FPU 数据并加载新进程的数据。
【解决方案2】:

在某些内核设计中,当“内核”或“系统”任务被任务切换出去时,浮点寄存器不会被保存。 (这是因为 FP 寄存器很大,需要时间和空间来节省。)所以如果你尝试使用 FP,值会随机“噗”。

此外,一些硬件浮点方案依赖内核通过陷阱来处理“奇数”情况(例如,零除法),并且所需的陷阱机制可能处于比内核任务更高的“级别”正在运行。

由于这些原因(以及更多原因),当您在任务中首次使用 FP 指令时,一些硬件 FP 方案会陷入困境。如果允许您使用 FP,则在任务中打开浮点标志,否则,您将被行刑队枪杀。

【讨论】:

  • 在 Linux 中,在代码之前/之后使用 kernel_fpu_begin() / kernel_fpu_end() 来触发用户空间 FPU 状态的保存/恢复(我猜你的内核 FPU 状态是针对抢占的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 2014-09-26
  • 2013-04-28
  • 1970-01-01
相关资源
最近更新 更多