【问题标题】:struct buffer_head inefficiencystruct buffer_head 效率低下
【发布时间】:2011-03-30 09:40:59
【问题描述】:

谁能说出直到 Linux Kernel 2.4 之前使用的 struct buffer_head 结构效率低下的原因,以及在内核 2.5.1 重新设计的新块层中使用的 struct bio 结构中实现了什么?

【问题讨论】:

    标签: linux operating-system kernel block


    【解决方案1】:

    在 2.5 之前的内核中,buffer_head 曾经是 IO 的 单元。但是,根据 buffer_head 执行 IO 可能效率低下。例如,跨越多个块的单个写入将导致创建多个 buffer_head 对象,从而浪费空间和时间。因此,buffer_head 结构最适合用于提供块到物理内存的映射,这正是它在 2.5 中所做的事情(也是它所做的唯一事情)从内核开始。


    另一方面,struct bio 被设计为以后内核版本中的 IO 单元。 **它代表当前在内核.** 请注意,块到内存的映射仍保留在 buffer_head 中。但是,buffer_head 现在没有被包含有关当前活动 IO 信息的字段重载。因此,当文件系统等更高级别的代码发出 IO 时,会将请求添加到 request_queue。该请求又包含一个指向 bio 结构的指针。控制发出 IO 的设备的设备驱动程序接收请求并提供服务。

    struct bio 结构也用于分割 IO,例如 RAID 磁盘设备驱动程序。查看 struct bio 定义,您会发现它维护了一个 io_vectors 数组(它们只是内存页的偏移量)。此外,bi_idx 用于索引这些 io_vec。通过为不同的磁盘使用不同的 bi_idx 值,每个磁盘将选择一组不同的 io_vec 来写入(或读取),因此 IO 将以真正的并行方式完成。

    【讨论】:

      【解决方案2】:

      使用源代码,卢克!

      来自include/linux/buffer_head.h:

      /*
       * Historically, a buffer_head was used to map a single block
       * within a page, and of course as the unit of I/O through the
       * filesystem and block layers.  Nowadays the basic I/O unit
       * is the bio, and buffer_heads are used for extracting block
       * mappings (via a get_block_t call), for tracking state within
       * a page (via a page_mapping) and for wrapping bio submission
       * for backward compatibility reasons (e.g. submit_bh).
       */
      struct buffer_head {
      [ ... ]
      

      来自linux/include/bio.h:

      /*
       * main unit of I/O for the block layer and lower layers (ie drivers and
       * stacking drivers)
       */
      struct bio {
      [ ... ]
      

      “高级”(通过文件系统的 I/O)和“低级”(通过块开发的 I/O)的两个分离 I/O 特征和操作。这允许更高的性能,因为在某处等待的缓冲层不会阻止块层在其他地方执行工作。关于它的一些解释可以在here 找到,Jens Axboe 简单地谈论它in this interview。

      【讨论】:

      • Answer 仅提供了结构的描述,并没有真正解释 为什么 一个比另一个效率低。此外,采访链接现在已断开,这是主要原因答案不应该这样做......
      【解决方案3】:

      Robert Love 的 LKD 3rd 对此有非常详细的解释。

      旧与新

      缓冲头和新的区别 bio 结构很重要。bio 结构代表一个 I/O 操作,它可能包括内存中的一个或多个页面。在另一 手,buffer_head结构代表一个单独的缓冲区,它 描述磁盘上的单个块。因为缓冲头被绑定到 单个页面中的单个磁盘块,缓冲区头导致 将请求不必要地划分为块大小的块,只是为了 稍后重新组装它们。由于生物结构重量轻,它 可以描述不连续的块并且不会不必要地拆分 I/O 操作。从 struct buffer_head 切换到 struct bio 提供 还有其他好处:

      • bio结构可以很容易的表示高内存,因为struct bio 只处理物理页而不处理直接指针。

      • bio 结构既可以表示普通页面 I/O,也可以表示直接 I/O(I/O 不通过页面缓存的操作——参见第 16 章,“ 页面缓存和页面写回”,用于讨论页面缓存)。

      • 生物结构使得执行分散收集(矢量化)变得容易 块 I/O 操作,以及操作中涉及的数据 源自多个物理页面。

      • 生物结构多 比缓冲头更轻量,因为它只包含 表示块 I/O 操作所需的最少信息,而不是 与缓冲区本身相关的不必要信息。

      【讨论】:

        猜你喜欢
        • 2016-12-04
        • 1970-01-01
        • 2015-02-14
        • 2015-10-06
        • 2020-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多