【问题标题】:What is the purpose of hard disk direct memory access?硬盘直接内存访问的目的是什么?
【发布时间】:2011-04-12 14:57:00
【问题描述】:

乍一看,让硬盘自行写入 RAM 似乎是个好主意,无需 CPU 指令复制数据,特别是考虑到异步网络的成功。但是直接内存访问 (DMA) 上的 Wikipedia article 声明如下:

使用 DMA,CPU 可以从这种开销中解放出来,并且可以在数据传输期间执行有用的任务(尽管 CPU 总线会被 DMA部分阻塞)。

我不明白公交线路如何“部分阻塞”。据推测,当时一台设备可以访问内存,然后看起来 CPU 实际上可以做的有用工作很少。它会在第一次尝试读取未缓存的内存时被阻止,我预计在 2 mb 缓存的情况下会非常快。

释放 CPU 以执行其他任务的目标似乎是无缘无故的。硬盘 DMA 是否会在实践中促进任何性能提升?

【问题讨论】:

    标签: memory io system cpu blocking


    【解决方案1】:

    1:PIO(编程 IO)破坏 CPU 缓存。从磁盘读取的数据在大多数情况下不会在之后立即处理。应用程序通常以大块的形式读取数据,但 PIO 以较小的块(通常为 64K IIRC)完成。因此,数据读取应用程序将等到大块传输完毕,而不会从控制器中获取的较小块立即在缓存中受益。同时,其他应用程序将遭受大部分缓存被传输驱逐的问题。这可能可以通过使用特殊指令来避免,这些指令指示 CPU 不要缓存数据,而是将其“直接”写入主存储器,但我很确定这会减慢复制循环的速度。从而造成的伤害甚至超过缓存抖动。

    2:PIO,因为它是在 x86 系统和可能大多数其他系统上实现的,与 DMA 相比确实很慢。问题不在于 CPU 不够快。问题源于总线和磁盘控制器的 PIO 模式的设计方式。如果我没记错的话,CPU 必须从所谓的 IO 端口读取每个字节(或使用 32 位 PIO 模式时的每个 DWORD)。这意味着对于每个 DWORD 数据,端口的地址必须放在总线上,并且控制器必须通过将数据 DWORD 放在总线上来响应。而当使用 DMA 时,控制器可以利用总线和/或内存控制器的全部带宽传输数据突发。当然,这种传统 PIO 设计还有很大的优化空间。 DMA 传输就是这样一种优化。仍然被认为是 PIO 的其他解决方案也可能是可能的,但是它们仍然会遇到其他问题(例如上面提到的缓存抖动)。

    3:内存和/或总线带宽不是大多数应用程序的限制因素,因此 DMA 传输不会停止任何事情。它可能会稍微减慢一些应用程序的速度,但通常它应该几乎不会被注意到。毕竟,与总线和/或内存控制器的带宽相比,所有磁盘都相当慢。提供> 500 MB / s的“磁盘”(SSD,RAID阵列)非常快。至少不能提供 10 倍于该数量的总线或内存子系统必须来自石器时代。 OTOH PIO 在传输数据块时确实会完全停止 CPU。

    【讨论】:

    • 好的,这是最好的答案。 DMA 是一种优化,理论上可以在没有特殊控制器的情况下实现,这是有道理的。
    【解决方案2】:

    我不知道我是否遗漏了什么。

    假设我们没有 DMA 控制器。每次从“慢”设备到内存的传输对于 CPU 来说都是一个循环

    ask_for_a_block_to_device 
    wait_until_device_answer (or change_task_and_be_interrupted_when_ready)
    write_to_memory
    

    所以CPU应该自己写内存。一块一块的。

    是否有必要使用 CPU 进行内存传输?不,我们使用另一个设备(或诸如 DMA 总线主控之类的机制)将数据传输到内存或从内存传输数据。

    与此同时,CPU 可能会做一些不同的事情,比如:用缓存做事情,但甚至在大部分时间都在访问内存的其他部分。

    这是关键部分:数据没有 100% 的传输,因为其他设备非常慢(与内存和 CPU 相比)。

    试图表示一个共享内存总线使用的例子(C 被 CPU 访问时,D 被 DMA 访问时)

    Memory Bus ----CCCCCCCC---D----CCCCCCCCCDCCCCCCCCC----D
    

    如您所见,内存一次访问一个设备。有时由 CPU,有时由 DMA 控制器。 DMA 次数很少。

    【讨论】:

    • +1 是解决 henle 对 没有 DMA 的系统如何工作的误解的唯一答案(这使得 DMA 的必要性非常清楚),并且也回答了 henle 的主要问题
    • 还应该提到的是,DMA 设备倾向于以突发方式而不是连续流来写入内存,这说明(以及它“较慢” 的事实)长期以来上图中读/写之间的时间。
    • 不过,这也是可能的:(C = CPU) (P = CPU transfer)CCCCCCCCCCPCCCCCCCCCCPCCCCCCCCCCC
    【解决方案3】:

    我不明白公交线路怎么会“部分阻塞”

    在多个时钟周期的一段时间内,有些会被阻塞,有些不会。引用University of Melbourne

    第二季度。什么是循环窃取?为什么要偷周期?

    A2。当 DMA 设备向内存传输数据或从内存传输数据时,它将 (在大多数架构中)使用与 CPU 使用相同的总线 访问内存。如果 CPU 想同时使用总线 作为 DMA 设备的时间,CPU 将停止一个周期,因为 DMA 设备具有更高的优先级。这是必要的,以防止 与小型 DMA 缓冲区溢出。 (CPU 永远不会出现溢出问题。)

    大多数现代 CPU 都有满足大多数内存引用的缓存 无需通过总线进入主存储器。 DMA将因此 对他们的影响要小得多。

    即使在进行 DMA 块传输时 CPU 完全处于饥饿状态,它也会比 CPU 必须坐在循环中将字节移入/移出 I/O 设备更快。

    【讨论】:

    • 那么你的意思是DMA控制器在循环中移动字节比CPU在循环中移动字节快?
    • @henle:他用 "shift" 表示 "transfer;" 它与二进制移位无关。请参阅Gonzalo's answer,我相信它更清楚。
    • 其实我说的也是转移,不是二元移位。
    【解决方案4】:

    磁盘控制器通常具有启用快速数据传输的特殊块传输指令。它们还可以突发传输数据,允许交错的 CPU 总线访问。 CPU 也倾向于突发访问内存,缓存控制器会在缓存行可用时填充它们,因此即使 CPU 可能被阻塞,最终结果只是缓存使用率下降,CPU 实际上并没有停止。

    【讨论】:

    • 写这篇文章,我的 390 MB 内存使用中只有 2 MB 驻留在我的 Core Duo L2 缓存中。我认为CPU会很快停止。一件事是访问缓存并获得性能提升,另一件事是缺少缓存并完全停止。
    【解决方案5】:

    一台计算机可以拥有多个 DMA 设备这一事实可能会提高性能。因此,使用 DMA,您可以并行进行多个内存读取,而无需 CPU 执行所有开销。

    【讨论】:

      【解决方案6】:

      无论如何,处理都不会发生在 CPU 总线上。 CPU 发出的可能会或可能不会触及内存的指令。当它们这样做时,它们通常首先针对 L1 缓存进行解析,然后在尝试内存之前解析 L2 和 L3。因此,DMA 传输不会阻塞处理。

      即使 CPU 和 DMA 传输都需要内存,预计它们也不会访问内存中的相同字节。实际上,内存控制器可能能够同时处理这两个请求。

      【讨论】:

      • “内存控制器可能能够同时处理这两个请求。”可能,但你有这方面的消息来源吗?
      【解决方案7】:

      如果您使用的是 Linux,则可以通过使用 hdparm 禁用 DMA 来非常轻松地进行测试。效果非常显着。

      【讨论】:

        猜你喜欢
        • 2011-02-11
        • 1970-01-01
        • 2010-11-01
        • 2020-05-22
        • 2015-02-01
        • 1970-01-01
        • 2011-04-01
        • 2015-07-18
        • 2019-03-17
        相关资源
        最近更新 更多