【问题标题】:Why does the Linux Kernel use the data structures that it does?为什么 Linux 内核使用它所使用的数据结构?
【发布时间】:2015-03-02 20:06:41
【问题描述】:

Linux 内核对 TCP 使用链表,对进程调度使用 RB 树。

就算法效率而言,这些是有道理的。您将一次收到一堆数据包,因此在列表末尾插入 O(1) 非常好。

对于进程调度,完全公平调度器使用红黑树,选择任务的时间为 O(1)。

据我所知,这些都不是以“平面”方式实现的——链表是一堆带有指向其他节点的指针的节点,就像树一样。这意味着据我所知,这些结构的位置应该很差。

据我所见,缓存局部性通常比算法效率更重要。

Linux 所针对的数据集是否有某些东西使得这些结构的算法效率超过了其他结构的缓存效率?

我是不是误会了什么?有人介绍过吗?

【问题讨论】:

  • 先生。 Torvalds,你的回应是什么?
  • 不同架构的缓存行大小差异很大。
  • 是的。但是内核真的针对纯平面内存模型进行了优化吗?

标签: c performance linux-kernel


【解决方案1】:

我对链表的使用有一个部分答案,我相信你会在this page about the CFS scheduler 中找到一些有趣的信息,特别是它提到了一个红黑树has good worst-case time for operations such as insert, search, and delete 确实看起来是一个非常理想的属性对于调度程序。

我敢打赌,是的,内核已经进行了很多分析,并且这些数据结构在现实世界中似乎表现良好。

This blog post 有一些关于内核链表使用情况的好数据。这些数据显然是在正常使用 3 天后通过保持每次操作的计数器完成而收集的。

+--------------------+-----------+
|     Operation      | Frequency |
+--------------------+-----------+
|     Empty Test     | 45%       |
|       Delete       | 25%       |
|        Add         | 23%       |
|   Iterate Start    | 3.5%      |
|   Iterate Next     | 2.5%      |
|     Replace        | 0.76%     |
| Other Manipulation | 0.0072%   |
+--------------------+-----------+

如您所见,实际访问元素的操作仅占总数的 6%,而插入和删除操作加起来几乎占一半。这是一个链表开始变得更有意义的用例。请注意,数据是在整个内核中收集的,而不是特别是 TCP 代码,因此每次使用链表的基本原理可能都不相同,但汇总数据确实表明这些选择总体上是明智的。

我认为同样重要的是要记住,内核的设计必须能够从最小的嵌入式设备扩展到处理大量数据的超级计算机,此时算法效率可能开始严重超过缓存问题。

【讨论】:

  • 很棒的链接/信息,谢谢。我想知道有多少设计是基于必须在众多系统上良好运行的。我会阅读更多关于此的内容。
猜你喜欢
  • 2017-04-08
  • 1970-01-01
  • 2012-07-18
  • 2014-07-01
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多