我写了一个内核模块来检查 CR4.PCIDE,它没有设置。为什么 Linux 不使用这样的特性来减少由于 TLB 失效和缓存污染而导致的性能下降?
请您参考如下方法:
Update: This changed around the 4.15 timeframe due to the Meltdown and Spectre attacks in late 2017 and early 2018. See the other answer for details.
注意:我不是 Linux 开发人员
对于英特尔的“进程上下文标识符”,有 4096 个 ID 的限制。这意味着当有超过 4096 个进程时,您需要管理它们(例如,可能会做一个“最近最少使用”的事情,以便如果需要执行当前没有 ID 的进程,那么 ID 是从一些其他过程并重复使用)。
另一件事是多 CPU 系统上的“TLB 击落”。这些可能有点贵,所以人们会采取一些技巧来避免它们。例如,如果一个进程只有一个线程,那么它只能在一个 CPU 上运行,并且您知道没有必要向其他 CPU 发送 IPI(中断它们并要求它们执行“TLB 击落”)。一旦开始使用 PCID,您就无法确定其他 CPU 是否仍然没有 TLB 条目,并且无法使用这些技巧来避免“TLB 击落”。这也意味着(理论上,对于实现不当的 PCID 支持)您从 PCID 获得的性能可能低于由于不可避免的 TLB 击落和 ID 管理开销而损失的性能,从而导致净损失。
我要说的主要是添加对 PCID 的支持有点复杂(这不像你可以在 CR4 中设置一个标志而忘记它)。您必须进行一些研究(实验、原型(prototype)、基准测试)以确定最有效的实现方式。对于大型/复杂/旧内核(如 Linux),它会更加复杂,因为您必须小心不要意外破坏其他东西。另一件事是此功能相对较新(如果我没记错的话,它只存在了几年)并且很多 CPU 都不支持(例如任何稍旧的 CPU,以及来自 AMD 的任何东西)。
基本上,我认为它归结为“时间与 yield ”(或者,没有足够的时间在有限数量的 CPU 上进行小的性能改进)。