DMA
DMA, 全称Direct Memory Access
,即直接存储器访问, 可以理解为外设与存储器直接进行数据传输(实际上不是直接)。
在DMA出现之前,CPU与外设之间通过系统总线
与其他部件连接, 采用轮询
/I/O中断
方式进行数据传输, 这些传输方式依赖CPU, 如果大规模数据传输的话,会产生大量的CPU中断,影响CPU运行效率。
假设我们只需要将外设A的数据拷贝到外设B,那是不是可以不需要CPU参与,只要给两种外设提供一条数据通路,再加上一些控制转移的部件就可以完成数据的拷贝?
正是基于上述的考虑,前辈们设计了DMA ,解决数据转移过度消耗CPU资源的问题, 主存与硬盘或网卡之间的数据传输可以绕开CPU的调度。
# 数据传输机制
Linux 提供了轮询
、I/O中断
以及DMA传输
这3种磁盘与主存之间的数据传输机制。
# 轮询
轮询方式是基于死循环对 I/O 端口进行不断检测,这种机制十分低效。
# I/O中断
I/O中断
传送方式是指当外设需要与CPU进行信息交换时,由外设向CPU发出请求信号,使CPU暂停正在执行的程序,转而去执行数据输入/输出操作,待数据传送结束后,CPU再继续执行被暂停的程序。
以磁盘读写为例,在DMA技术出现之前,应用程序与磁盘之间的I/O操作都是通过CPU的中断完成的。 每次用户进程读取磁盘数据时,都需要CPU中断,然后发起I/O请求等待数据读取和拷贝完成,每次的I/O中断都导致CPU的上下文切换,大概过程如下:
- 用户进程向CPU发起
read
系统调用读取数据,由用户态切换为内核态,然后一直阻塞等待数据的返回。 - CPU 在接收到指令以后对磁盘发起 I/O 请求,将磁盘数据先放入磁盘控制器缓冲区。
- 数据准备完成以后,磁盘向 CPU 发起 I/O 中断。
- CPU 收到 I/O 中断以后将
磁盘缓冲区
中的数据拷贝到内核缓冲区
,然后再从内核缓冲区
拷贝到用户缓冲区
。 - 用户进程由内核态切换回用户态,解除阻塞状态,然后等待 CPU 的下一个执行时间钟。
# DMA
继续以磁盘读写为例, DMA传输则在 I/O中断
的基础上引入了DMA磁盘控制器,由DMA磁盘控制器
负责数据的传输,降低了I/O中断
操作对CPU资源的大量消耗。有了DMA磁盘控制器
接管数据读写请求以后,CPU从繁重的I/O操作中解脱,数据读取操作的流程如下:
- 用户进程向CPU发起read系统调用读取数据,由用户态切换为内核态,然后一直阻塞等待数据的返回。
- CPU在接收到指令以后对 DMA 磁盘控制器发起调度指令。
- DMA磁盘控制器对磁盘发起 I/O 请求,将磁盘数据先放入磁盘控制器缓冲区,CPU 全程不参与此过程。
- 数据读取完成后,DMA 磁盘控制器会接受到磁盘的通知,将数据从磁盘控制器缓冲区拷贝到内核缓冲区。
- DMA 磁盘控制器向 CPU 发出数据读完的信号,由 CPU 负责将数据从内核缓冲区拷贝到用户缓冲区。
- 用户进程由内核态切换回用户态,解除阻塞状态,然后等待 CPU 的下一个执行时间钟。
# DMA原理
DMA传输是将数据从一个地址空间复制到另外一个地址空间。由CPU初始化这个传输动作,传输动作本身是通过DMA控器
来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区,这样的操作并没有让CPU阻塞,CPU可以继续去处理其他的工作。DMA传输对于高效能数据传输是很重要的。
# 总线控制权转移问题
总线的控制一直是由CPU负责,而在实现DMA传输时,是由DMA控制器
直接掌管总线,因此,存在着一个总线控制权转移问题
。
即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。
- DMA传输开始前:CPU------>DMA控制器
- DMA传输结束后:DMA控制器------>CPU
# DMA传输过程
一个完整的DMA传输过程必须经过DMA请求
、DMA响应
、DMA传输
、DMA结束
4个步骤。
- DMA请求
CPU对DMA控制器初始化,并向I/O接口发出操作命令,I/O接口提出DMA请求。
- DMA响应
DMA控制器对DMA请求判别优先级及屏蔽,向总线裁决逻辑提出总线请求。当CPU执行完当前总线周期即可释放总线控制权。此时,总线裁决逻辑输出总线应答,表示DMA已经响应,通过DMA控制器通知I/O接口开始DMA传输。
- DMA传输
DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,由DMA控制器输出读写命令,直接控制RAM与I/O接口进行DMA传输。 在DMA控制器的控制下,在存储器和外部设备之间直接进行数据传送,在传送过程中不需要中央处理器的参与。开始时需提供要传送的数据的起始位置和数据长度。
- DMA结束
当完成规定的成批数据传送后,DMA控制器即释放总线控制权,并向I/O接口发出结束信号。
当I/O接口收到结束信号后,一方面停 止I/O设备的工作,另一方面向CPU提出中断请求,使CPU从不介入的状态解脱,并执行一段检查本次DMA传输操作正确性的代码。
最后,带着本次操作结果及状态继续执行原来的程序。
由此可见,DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,使CPU的效率大为提高。
# 总结
目前大多数的硬件设备,包括磁盘控制器、网卡、显卡以及声卡等都支持DMA技术。通过DMA技术,IO设备跟用户程序空间传输数据的过程中,减少数据拷贝次数,减少系统调用,实现 CPU的零参与,彻底消除CPU在这方面的负载。