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

在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

阅读更多:   杂谈
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif