Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 操作系统

    • 学习笔记

      • 鸟哥的Linux私房菜学习笔记01-计算机概论
      • 鸟哥的Linux私房菜学习笔记02-磁盘分区
      • 鸟哥的Linux私房菜学习笔记03-日志文件
      • 寄存器
      • 汇编语言
      • 零拷贝
      • 内存管理单元MMU
      • 内存管理基础知识
      • 文件系统
      • 系统调用
      • 写时复制
      • 虚拟地址
      • 虚拟内存
      • 中断
      • CPU
      • DMA
        • 数据传输机制
          • 轮询
          • I/O中断
          • DMA
        • DMA原理
          • 总线控制权转移问题
          • DMA传输过程
        • 总结
      • mmap
      • Swap分区
    • Shell

    • Linux命令

    • RAID分类详解
    • Page Cache与Page回写
    • 磁盘IO与swap分区
  • 计算机网络

  • 数据结构和算法

  • MySQL

  • Redis

  • Nginx

  • MongoDB

  • 其他

  • 计算机基础
  • 操作系统
  • 学习笔记
Ravior
2019-02-09
目录

DMA

DMA, 全称Direct Memory Access,即直接存储器访问, 可以理解为外设与存储器直接进行数据传输(实际上不是直接)。

Gitlib

在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的上下文切换,大概过程如下:

Gitlib

  • 用户进程向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操作中解脱,数据读取操作的流程如下:

Gitlib

  • 用户进程向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在这方面的负载。

#操作系统
上次更新: 2022/12/01, 11:09:34
CPU
mmap

← CPU mmap→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式