diff -u:加速不可加速之物

作者:Zack Brown

有时,内核开发人员可能会并行工作多年而没有意识到这一点。这是分布式系统的一种低效之处,当您有足够的贡献者来分担额外的劳动时,这往往会成为一种优势——这有点像“集思广益,漏洞无处遁形”的道理。

这一次,Kirill A. Shutemov 想要解决内存加密代码中的一个特殊问题。内存加密发生在内核中一个使用非常频繁的地方,以至于即使只有几个操作码的差异,也会对正在运行的系统产生明显的速度差异。为了节省这几个 汇编 指令,任何不引入安全漏洞的方法都值得考虑。

但是 Kirill 遇到了一个问题——他的代码让情况变得更糟。他想将 __PHYSICAL_MASK 变量转换为他所谓的“可修补常量”——一个在运行时具有常量简单性的值,但可以通过配置选项或在引导加载程序命令行在系统启动之前动态设置的值。

到目前为止,他提出了一个可以做到这一点的补丁——并且该补丁也适用于其他可能更快地实现为常量的变量。不幸的是,正如所实现的,尽管它实现了他想要的功能,但它导致 GCC 生成的代码效率低于之前的代码。这不仅没有加速,反而导致他的测试系统速度降低了 0.2%。

他发布了他的补丁,并向 linux-kernel 邮件列表请求想法。

Linus Torvalds 回复了对 GCC 生成的操作码的分析,解释了为什么它们速度较慢,以及为什么 Kirill 的通用方法总是会遇到速度减慢的问题。特别是,Linus 指出 Kirill 将常量值移动到寄存器中,这永远不会是最佳的,并且他的代码还包含一个 movabsq 指令,他认为这很少需要。

Linus 说他实际上非常想要这个功能,尽管实现它需要复杂的开销;事实上,他更喜欢一种更复杂的方法,类似于 H. Peter Anvin 大约 18 个月前尝试过的方法。对于那种方法,他说

它相当复杂,但它实际上带来了更大的优势。代码本身会更好,更小。但是代码的 *基础设施* 变得相当棘手。

Peter 回复说,他实际上一直在一个秘密的、未公开的地点,在一个无名小镇的井底从事这个项目已经有一段时间了。事实上,他目前的方法比他 18 个月前尝试的方法更雄心勃勃(也更复杂)。另一方面,正如他所说,他现在已经完成了整个项目的 85% 左右,代码“主要需要清理、测试和分解成合理的块”。他补充说

我还没有提交它的主要原因是我有点过于雄心勃勃,想要实现更多复杂的子案例,例如 32 位内核上的 64 位移位。在这种情况下,优势实际上非常巨大,但这需要数据相关的代码修补,而不仅仅是立即修补,这需要增强 alternatives 框架。

因此,Kirill 的问题似乎即将被 Peter 解决。内核中如此深入和复杂的一个元素,以至于似乎永远不会被触及,正在被分解开来,超出了其明显的自然限制。而且,所有这一切都是通过仅仅添加一大堆极其复杂的代码来实现的,即使是经验丰富的开发人员也对触及它感到犹豫。

注意:如果您在上面被提及并想在评论区上方发布回复,请将您的回复文本发送至 ljeditor@linuxjournal.com。

Zack Brown 是 Linux JournalLinux Magazine 的科技记者,并且是 “Kernel Traffic” 每周新闻通讯和 “Learn Plover” 速记打字教程的前作者。他于 1993 年在他的 386 电脑上安装了 Slackware Linux,配备了 8MB 内存,并被开源社区彻底震撼。他是 Crumble 纯策略棋盘游戏的发明者,您可以用几块纸板自己制作。他还喜欢写小说、尝试动画、改革拉班舞谱、设计和缝制自己的衣服、学习法语以及与朋友和家人共度时光。

加载 Disqus 评论