ChatGPT解决这个技术问题 Extra ChatGPT

Linux内核中浮点的使用

我正在阅读 Robert Love 的“Linux Kernel Development”,我遇到了以下段落:

否(容易)使用浮点 当用户空间进程使用浮点指令时,内核管理从整数到浮点模式的转换。内核在使用浮点指令时必须做什么因架构而异,但内核通常会捕获一个陷阱,然后启动从整数模式到浮点模式的转换。与用户空间不同,内核没有对浮点的无缝支持的奢侈,因为它不能轻易地陷入困境。在内核中使用浮点需要手动保存和恢复浮点寄存器,以及其他可能的琐事。简短的回答是:不要这样做!除了极少数情况外,内核中没有浮点运算。

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

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

D
DigitalRoss

因为...

许多程序不使用浮点或不在任何给定的时间片上使用它;和

保存 FPU 寄存器和其他 FPU 状态需要时间;所以

...操作系统内核可能会简单地关闭 FPU。 Presto,没有要保存和恢复的状态,因此更快的上下文切换。 (这就是模式的意思,它只是意味着启用了 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 数据并加载新进程的数据。
H
Hot Licks

对于某些内核设计,当“内核”或“系统”任务被任务切换时,浮点寄存器不会被保存。 (这是因为 FP 寄存器很大,需要时间和空间来保存。)因此,如果您尝试使用 FP,值将随机“噗”。

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

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


在 Linux 中,在代码之前/之后使用 kernel_fpu_begin() / kernel_fpu_end() 来触发用户空间 FPU 状态的保存/恢复(我猜你的内核 FPU 状态反对抢占)。
t
tjarco

关于内核空间中的浮点使用,我得到了这个结果。我想知道的是,这不是一个“旧的”实现(兼容性),因为旧的架构在巫婆中实现了专用的 FPU,并且 FPU 指令被外包给拥有自己的管道的物理“协处理器”?

我可以想象,由于流水线延迟等原因,这样的架构应该以不同的方式处理“外包”指令,但我记得当前架构(Arm.v8)将其 IEEE754 指令作为指令集的一部分,而不是作为外部 FPU-模块。所以无法开启或关闭,也不存在流水线延迟的问题。是的,可能一些应该保存/恢复的 CORE 寄存器,但这似乎可以忽略不计(与堆栈管理的开销相比)。

在我看来,没有理由不在内核中使用浮点数。如上所述,它已经在内核空间中用于 RAID。


您好,欢迎来到 StackOverflow。您回答的问题已经有 9 年历史了,还有另外 2 个得到好评的答案。因此,在发布此类旧问题的答案之前,请确保它包含新信息。
如果您有新问题,请点击 Ask Question 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review