11

CPU处理简单重复的数据传输太浪费了,因此设计了DMA,什么是DMA?它传输数据比CPU快吗...

 3 years ago
source link: https://blog.popkx.com/cpu%E5%A4%84%E7%90%86%E7%AE%80%E5%8D%95%E9%87%8D%E5%A4%8D%E7%9A%84%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E5%A4%AA%E6%B5%AA%E8%B4%B9%E4%BA%86-%E5%9B%A0%E6%AD%A4%E8%AE%BE%E8%AE%A1%E4%BA%86dma/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在C语言程序开发中,常常需要将内存中的数据从地址A拷贝到地址B,虽说 CPU 访问内存的速度非常快,但是拷贝总归是要消耗 CPU 时间的。如果需要拷贝的数据比较长,那么拷贝动作将会消耗相当多的 CPU 时间,在此期间,CPU 不能做任何别的事情。

粗略来看,数据的拷贝过程并不复杂,无非就是寻址+写入数据,CPU 把时间花在处理这样的“简单重复劳动”上就太浪费了,因此,DMA 就被设计出来了。

DMA 简介

DMA 的英文全称是 direct memory access,直译过来就是“直接存储器存取”的意思,是计算机系统的一个特性。正如前文所讨论的,DMA 允许某些硬件子系统读写系统存储器,而不依赖于 CPU。简单来说,就是可以在不占用 CPU 时间的情况下,实现数据在存储器间传输(拷贝,移动等)。

在没有 DMA 的情况下,CPU 在处理数据的输入/输出时,通常会在数据读写器件完全被占用,因而无法执行其他工作。相反,如果系统有 DMA,CPU 只需完成数据传输的初始化,接下来的数据传输完全由 DMAC(DMA controller,DMA 控制器)实现,CPU 可以在数据传输过程中执行其他操作。

如果计算量很大,CPU 可能无法跟上数据传输的速率,那么 DMA 的存在可以让 CPU 专心处理数据的计算,而无需再抽空执行数据传输操作,这无疑可以提升系统的效率。另一方面,对于相对较慢的 I/O 数据,CPU 也无需再花时间等待数据传输完成。

如今 DMA 已被广泛用于各种硬件系统,包括磁盘驱动器控制器、显卡、网卡和声卡。DMA 还用于多核 CPU 中的芯片内数据传输。有 DMA 通道的计算机在传输数据时,CPU 开销要小得多。类似地,多核 CPU 内的处理元件可以在不占用 CPU 时间的情况下向本地存储器传输数据,从而允许并行进行计算和数据传输。

此外, DMA 还可用于“存储器到存储器”的复制或移动,可以将较大开销的内存操作(如大拷贝或分散收集操作)从 CPU 转为专用的 DMA。简言之,DMA 在片上网络和存储器计算体系结构中具有重要意义。

DMA 控制器

到这里,读者应该明白 DMA 是一个好用的数据传输系统,但真正控制数据传输的其实是 DMA 控制器。DMA 控制器可以生成内存地址并启动存储器读写周期,一般具有若干个硬件寄存器,包括存储器地址寄存器、字节计数寄存器以及控制寄存器。

CPU 通过读写这些硬件寄存器控制 DMA 控制器实现数据传输,一般要指定数据的来源,要传往的目的地,以及传输方向(从 I/O 设备读取或者写入)、传输单元的大小。CPU 通过寄存器完成这些设置项后,即可命令外围设备启动数据传输,DMA 控制器会自动增加其内部地址寄存器,直到传输完整的数据块。

当外围设备成为数据总线主设备时,DMA 可以将数据直接写入系统内存,而无需 CPU 的参与,也因为如此,C语言程序员需要提供一些措施,以避免发生总线抢占冲突。DMA 可以一次只传输一个字节,也可以在 burst 模式(突发模式)下一次传输所有字节。如果是前者,CPU 在交替的总线周期上访问内存。

缓存一致性问题

DMA 并不是只有好处没有坏处的。现代 CPU 大都带有高速缓存(存取速度远高于外部内存),CPU 访问外部内存某个地址的时候,暂时先将新的值写入高速缓存中,如果 CPU 还未来得及将外部内存数据更新,DMA 操作的是外部内存的数据,将读取到未更新(但实际上已经更新)的数据。

类似的,如果通过 DMA 将外部设备产生的新数据写到外部内存内,而 CPU 从高速缓存里读取数据将得到尚未更新的数据。一般来说,这样的问题有两种方法可以解决:

  1. 基于缓存同调系统(Cache-coherent system),也即以硬件方法解决,当设备将数据写到外部内存时,以一个信号来通知高速缓存控制器更新数据。
  2. 非同调系统,也即以软件方法完成,操作系统必须确认缓存读取时,DMA 已经完成或者已经被禁止。显然,这种方法会增加 DMA系统的负担。

DMA 传输数据比 CPU 更快吗?

这其实是一个奇怪的问题。之所以有这个小标题,是因为在我的上一篇文章讨论C语言库函数 memcpy() 为什么高效率时,有读者痛批我胡言乱语,认为 memcpy() 效率高是因为有 DMA 介入。

经过前面的介绍,相信读者已经明白 DMA 其实就是方便数据传输的一个系统而已,它可以不依赖 CPU 传输数据。但是这样的特性并不能说明它传输数据就一定比 CPU 传输快。严格来说,二者传输数据并无明确的效率对比,但是结合实际应用,可以分以下两种情况考虑:

  1. CPU 比 DMA 快。
    如果 CPU 是空闲的,系统内仅有数据传输任务,或者数据传输任务的优先级最高,并且系统中断被禁止,简言之,就是 如果 CPU 可以专心执行数据传输工作,那么 CPU 传输数据肯定比 DMA 快。因为一般来说,CPU 时钟要比总线(例如 ARM 中的 AHB)时钟快得多,而 DMA 是使用总线时钟的。
  2. DMA 比 CPU 块。
    在有操作系统的系统中,很难保证数据传输任务独享 CPU,此时 CPU 可能需要花大把时间处理数据传输任务之外的任务,综合来看,DMA 传输数据的速率就可能会比 CPU 传输数据的速率高了。

如果 CPU 把大把时间花在处理“简单重复”的数据传输上就太浪费了,因此 DMA 系统就被设计出来了。本文简要介绍了一下 DMA 的基本特性,在了解这些特性后,容易看出,设计 DMA 并不是为了解决 CPU 拷贝数据过慢的问题,而是为了将 CPU 解放出来,使其尽量将精力放在其他任务中而已。

https://stackoverflow.com/questions/38016941/how-does-burst-mode-dma-speed-up-data-transfer-between-main-memory-and-i-o-devic

https://stackoverflow.com/questions/43436562/in-what-cases-cpu-direct-transfer-works-faster-than-dma-in-what-cases-dma-trans

https://en.wikipedia.org/wiki/Direct_memory_access

https://stackoverflow.com/questions/tagged/c?tab=votes&page=49&pagesize=15


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK