
文章插图
什么是 DMA ?没有 DMA,计算机程序访问磁盘上的数据I/O 的过程是这样的:
- CPU 先发出读指令给磁盘控制器(发出一个系统调用),然后返回;
- 磁盘控制器接受到指令,开始准备数据,把数据拷贝到磁盘控制器的内部缓冲区中,然后产生一个中断;
- CPU 收到中断信号后,让出CPU资源,把磁盘控制器的缓冲区的数据一次一个字节地拷贝进自己的寄存器,然后再把寄存器里的数据拷贝到内存,而在数据传输的期间 CPU 是无法执行其他任务的 。

文章插图
可以看到,整个数据的传输有几个问题:一是数据在不同的介质之间被拷贝了多次;二是每个过程都要需要 CPU 亲自参与(搬运数据的过程),在这个过程,在数据拷贝没有完成前,CPU 是不能做额外事情的,被IO独占 。
如果I/O操作能比较快的完成,比如简单的字符数据,那没问题 。如果我们用万兆网卡或者硬盘传输大量数据,CPU就会一直被占用,其他服务无法使用,对单核系统是致命的 。
为了解决上面的CPU被持续占用的问题,大佬们就提出了 DMA 技术,即直接内存访问(Direct Memory Access) 技术 。
那到底什么是 DMA 技术?
所谓的 DMA(Direct Memory Access,即直接存储器访问)其实是一个硬件技术,其主要目的是减少大数据量传输时的 CPU 消耗,从而提高 CPU 利用效率 。其本质上是一个主板和 IO 设备上的 Dmac 芯片 。CPU 通过调度 DMAC 可以不参与磁盘缓冲区到内核缓冲区的数据传输消耗,从而提高效率 。
那有了DMA,数据读取过程是怎么样的呢?下面我们来具体看看 。

文章插图
详细过程:
- 用户进程a调用系统调用read 方法,向OS内核(资源总管)发出 I/O 请求,请求读取数据到自己的内存缓冲区中,进程进入阻塞状态;
- OS内核收到请求后,进一步将 I/O 请求发送 DMA,然后让 CPU 执行其他任务;
- DMA 再将 I/O 请求发送给磁盘控制器;
- 磁盘控制器收到 DMA 的 I/O 请求,把数据从磁盘拷贝到磁盘控制器的缓冲区中,当磁盘控制器的缓冲区被写满后,它向 DMA 发起中断信号,告知自己缓冲区已满;
- DMA 收到磁盘的中断信号后,将磁盘控制器缓冲区中的数据拷贝到内核缓冲区中,此时不占用 CPU,CPU 可以执行其他任务;
- 当 DMA 读取了一个固定buffer的数据,就会发送中断信号给 CPU;
- CPU 收到 DMA 的信号,知道数据已经Ready,于是将数据从内核拷贝到用户空间,结束系统调用;
零拷贝技术实现的方式常见的有2种,而今引入持久化内存后,还有App直接访问内存数据的方式,这里先不展开 。下面介绍常用的2种方案,它们的目的减少“上下文切换”和“数据拷贝”的次数 。
- mmap + write(系统调用)
- sendfile
read() 系统调用:把内核缓冲区的数据拷贝到用户的缓冲区里,用 mmap() 替换 read() ,mmap() 直接把内核缓冲区里的数据映射到用户空间,减少这一次拷贝 。
buf = mmap(file, len);write(sockfd, buf, len); 
文章插图
具体过程如下:
- 应用进程调用了 mmap() 后,DMA 会把磁盘的数据拷贝到内核的缓冲区里 。因为建立了这个内存的mapping,所以用户态的数据可以直接访问了;
- 应用进程再调用 write(),CPU将内核缓冲区的数据拷贝到 socket 缓冲区中,这一切都发生在内核态
- DMA把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里
推荐阅读
- 高质量发展|求职者都带简历了,为什么HR还要让你填表?一文讲透了
- 辟谣:猫咪的语言是喵?教你读懂“猫言猫语”,让你明白猫的内心
- 有糖尿病究竟还能不能吃水果了?怎么吃比较合理?医生一文讲清
- 庄家洗盘洗多久才拉升?散户还想一卖就飞吗?一文掌握洗盘特征!
- 到底是普通痣?还是黑色素瘤?医生一文助您自检
- 香港24小时丨香港9月1日发生了什么?一文速览
- 教你读懂医生的职称 研究员职称
- 万字长文读懂直播:很多人没明白直播带货到底要做什么?
- Win10如何修改电脑用户名? 电脑用户名
- 电脑分辨率多少合适 电脑分辨率
