从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • 计算机简史

  • 数字电路

  • 计算机组成原理

    • 计算机组成原理(北大-陆俊林)

      • 概述-计算机组成原理(北大-陆俊林)
      • 第1周-计算机组成章节视频简介
      • 101-电子计算机的兴起
      • 102-冯·诺依曼结构的要点
      • 103-冯·诺依曼结构的小故事
      • 104-计算机结构的简化模型
      • 105-计算机执行指令的过程
      • 106-计算机输入和输出
      • 107-冯诺依曼结构和具体实现
      • 201-设计自己的计算机
      • 202-x86 体系结构
      • 203-x86 指令简介
      • 204-复杂的 x86 指令举例
      • 205-MIPS 体系结构
      • 206-MIPS 指令简介
      • 301-算术运算和逻辑运算
      • 302-门电路的基本原理
      • 303-寄存器的基本原理
      • 304-逻辑运算的实现
      • 305-加法和减法的实现
      • 306-加法器的优化
      • 401-乘法的运算过程
      • 402-乘法器的实现
      • 403-乘法器的优化 1
      • 404-乘法器的优化 2
      • 405-除法的运算过程
      • 406-除法器的实现
      • 407-除法器的优化
      • 501-处理器的设计步骤
      • 502-数据通路的建立
      • 503-运算指令的控制信号
      • 504-访存指令的控制信号
      • 505-分支指令的控制信号
      • 506-控制信号的集成
      • 601-流水线的基本原理
      • 602-流水线的优化
      • 603-超标量流水线
      • 604-流水线的冒险
      • 605-数据冒险的处理
      • 606-控制冒险的处理
      • 701-存储层次结构概况
      • 702-DRAM 和 SRAM
      • 703-主存的工作原理
      • 704-主存技术的发展
      • 705-高速缓存的工作原理
      • 706-高速缓存的组织结构
      • 707-存储容量的计算
      • 801-中断和异常的来源
      • 802-中断向量表的结构
      • 803-中断向量表的发展
      • 804-中断的处理过程
      • 805-内部中断分类说明
      • 806-基于中断的功能调用
      • 901-输入输出接口的基本功能
      • 902-输入输出接口的编址方式
      • 903-输入输出的控制方式
      • 904-中断控制方式
      • 905-外部中断的处理过程
      • 906-直接存储器访问方式
        • 独立的 DMA 控制器
    • 字符编码入门

  • 操作系统

  • Linux

  • 计算机网络

  • 数据库

  • 编程工具

  • 装机

  • 计算机基础
  • 计算机组成原理
  • 计算机组成原理(北大-陆俊林)
2023-06-13
目录

906-直接存储器访问方式

# 906-直接存储器访问方式

我们还是来说快递的事。 有一天,你在这坐着运算,突然来电话了, 然后你接了一听,啊, 又有快递啦,啊什么?一千本书, 现在就得去拿,哎呀,好好好。 这个怎么办呢?这个,这搬一千本书又得浪费很多时间, 呃,好办,啊那我们就叫一个搬家公司, 跟他们说好,我们要从哪搬到哪谈好价钱,他们就去搬, 并且告诉他们搬完之后呐给我来一个电话,然后我去检查,这就可以了。 那么,虽然要多花一些钱,但是如果能够运算更重要的任务, 那还是值得的。这就是我们要说的 DMA 方式。

‍‍

现在的计算机中有很多复杂的外设比如像显示器,网络,硬盘, 这些外设需要传输的数据量很大,而且对传输的速率也有很高的要求, 如果这些数据都要靠 CPU 一个一个来搬运的话,那恐怕就难以应对了,所以这就需要用到 DMA 这种 IO 控制方式。

DMA 就是直接存储器访问的简称。 那如果采用 DMA 方式进行 I/O 数据的传送在传送的过程中是不需要 CPU 干预的,这个数据传送的工作是由一个专门的硬件电路控制,可以直接将外设的数据传到存储器或者将存储器中的数据传到外设, 而这个专门的硬件控制电路就称为 DMA 控制器,简称为 DMAC, 其实 DMA 控制器本身也是一个 I/O 口, 和其他 I/O 接口类似,它早期也是采用独立芯片的形式, 而现在通常是寄存在其他多功能的芯片当中。

​

那我们来看 DMA 控制器的基本工作步骤。 这是一个简化的系统,里面有一个 CPU,一个存储器, 一个 I/O 接口,还有一个 DMA 控制器,它们通过系统总线连接在一起, 这里还(给部件)增加了 m 和 s 这两种标记,m 是 master 的缩写, 表示这个部件可以在系统总线上主动发起传输, 比如 CPU 就是这样的部件,它可以在系统总线上主动发起读写的传输。 而 s 是 slave 的缩写,它表示这个部件只能被动地接受来自系统总线的传输。 那存储器就是一个典型的只有 slave 接口的设备。 一般的 I/O 接口也是这样,只会接受来自 CPU 的访问, 而 DMA 控制器则是既有 master 接口又有 slave 接口。

那我们就要用这个 DMA 控制器进行一次外设到内存的传送, 我们可以把这个 I/O 接口看成是网卡,外面接着网线, 现在我们需要用 DMA 的方式接收一个网络包,并保存到存储器的某个区域, 那要完成这个操作,CPU 首先需要设置 DMA 内部的配置寄存器,那对于 x86CPU,我们就要用 out 指令续写 DMA 控制器当中的一些 I/O 端口,以配置好它的工作模式, 然后这个 DMA 控制器就处于空闲等待状态,而 CPU 也可以去执行其他的程序了。

​ ‍

那当外设送来数据到 I/O 接口的时候, I/O 接口就会像 DMA 控制器发出 DMA 传送的申请, 这个申请需要通过一根额外的连线发出, 那 DMA 控制器收到 I/O 接口的申请之后,还会通过另一个连线响应这个申请, 然后 DMA 控制器就会通过它的 master 接口发起总线读传输, 而这个读传输的地址就是这个 I/O 接口当中的数据输入缓冲寄存器。 那这样数据就会从 I/O 接口被读到了 DMA 控置器当中,然后 DMA 控制器会向存储器发起总线的写传输,将刚才读回的这个数据写到存储器的某个区域。 ​

我们注意在有 DMA 控制器之前, 这个系统当中只有 CPU 可以发起总线传输, 而现在 DMA 控制器可以主动发起总线传输了。 那接下来 DMA 控制器会重复五和六这两个动作, 不断地从 I/O 接口中读出数据再写到存储器当中去, 那如果这时网络传输一直到收完一个网络包, 就次 DMA 传送才算完成,然后 DMA 控制器会返回到第二步,等待 I/O 发起下一次 DMA 传送的申请。

​

那一次 DMA 传送的数据可能很多, 所花的时间也很长,但是在这段时间 CPU 一直可以在执行其他的程序, 这样就和数据传送的工作并行起来,可以获得很好的系统性能。 但是 CPU 怎么知道 DMA 传送已经完成了呢?那通常情况下 DMA 传送完成后,DMA 控制器会发出一个中断请求信号,通过中断控制器通知 CPU, 那这个 DMA 控制器发出的中断,也是一个外部中断,后面的处理过程就和其他 I/O 接口发出的中断是一样的, 只不过它对应的中断服务程序是让 CPU 来对这一次的 DMA 传输进行处理。

​

所以从这个步骤我们可以看出 DMA 方式也不是完全不用 CPU 来干预,在 DMA 启动的时候 CPU 来进行配置 而传送完成后 CPU 还需要来进行处理。 那后续的处理根据任务的需要各有不同,而初始化的配置却大体是一样的。

在 DMA 传送开始前 CPU 要设置 DMA 控制器内部的寄存器, 一般至少要设置这么几项,既然等一会儿 DMA 控制器要进行数据的传送, 那就需要先设置好从哪里开始传,这也就是源地址的初始值。 还需要设置在传送的过程中这个源地址是递增还是递减,然后还需要 设置这些数据传输到哪里,也就是目的地址的初始值以及传送时的地址增减方式。 最后还要设置需要传送多少数据。

那么我们还是以刚才提到的外设到内存的传送为例。 那 CPU 在初始化配置时,会将某个源地址设为 I/O 端口, 比如就是一个网络控制器的数据输入寄存器端口, 而且传送时这个源地址是不变的。 因为每一次 DMA 控制器都是从同一个 I/O 端口读出数据,

而目的地址要设置为存储器的某个地址, 而且传送时是递增的,这样 DMA 控制器每次从 I/O 接口当中读出一个数就把这个数写到存储器当中去, 下一次再读出一个数再写到存储器当中时地址就应该递增, 这样才不会覆盖刚才传过来的这个数。

第三要设置待传送数据的长度,那如果是从外设接收数据, CPU 在配置时可能不知道究竟这个数据有多长, 那就可以不设置这个参数。

最后根据 I/O 接口的控制信号来判断是否传输完成。

那如果是从存储器发送一组数据到 I/O 接口, 这个时候 CPU 在初始化时就是知道究竟要发送多长的数据。 那就需要设置这个待传送数据的长度的这个参数。

那需要强调的是, 这些参数都是 DMA 控制器内部的寄存器,一般各自都有一个 I/O 端口的地址, 那么编程时通过 out 指令让 CPU 去写这些 I/O 端口,从而配置好了源地址,目的地址和待传送数据的长度等信息,DMA 控制器在运行的过程中就不需要再靠 CPU 执行程序来控制,而是直接查看内部的源地址寄存器,就把对应的地址发到系统总线上, 就从 I/O 接口读回了相应的数据,然后再查看自己的目的地址寄存器, 把这个地址和刚才读回来的数据一起发到系统总线上,这样就写入到了存储器当中去。 而每读写一次, 就在内部累计已经传送的数据的长度,并和这个待传送数据的长度的寄存器的内容进行比较, 如果相等则意味着传输已经完成,如果还不等则继续传输。 所以 CPU 在一次配置完之后,后续的工作都由 DMA 控制器的内部硬件自动完成, 不再需要 CPU 的干预了。这就是所谓直接存储器访问的含义。

​ ‍

# 独立的 DMA 控制器

那在最早的个人计算机当中是没有 DMA 控制器的, 那后来为了提高输入输出的效率,就增加了独立的 DMA 控制器的芯片。例如刚才提到的 8237, 那通过 CPU 设置 DMA 控制器当中的不同的地址就可以为不同的 I/O 接口提供 DMA 的服务。

但是随着计算机的发展有一些 I/O 接口的速度越来越快, 对 DMA 传输的要求也越来越高。 那多个 I/O 接口共享一个独立的 DMA 控制器的方式可能就没有办法满足部分 I/O 接口的需求了。

​

这时就出现了自带 DMA 控制器的 I/O 接口, 那这样的 I/O 接口内部带有一个专属的 DMA 控制器,只为这个 I/O 接口提供服务,那这个 I/O 接口现在也有了 master 的总线接口。 那在显卡、网卡、硬盘控制器这些对传送率要求很高的 I/O 接口中一般都会自带 DMA 控制器, 那在系统初始化时,CPU 要配置好各个 DMA 控制器, 然后外设有传输需求时这些 DMA 控制器就可以自动地开始工作了。

那如果我们把这个独立的 DMA 控制器比作一个搬家公司, CPU 就请这个搬家公司来完成 I/O 接口和存储器之间的数据搬运工作。 而有些部门的搬运工作量非常大, 实际上需要一个搬家公司全时地为他们服务才能够满足需求。 于是他就在部门内部自己组建了一个搬运队。 那这样一旦有数据传送的需求就可以马上开始工作,而不需要去申请外部的这个 DMA 控制器了,传输的效率自然会大大提升。

而且不同的 I/O 接口有不同的传输的特点,比如显示、网络、硬盘传输的行为肯定有不同的特征,而内线的 DMA 控制器就可以根据 I/O 接口的特点进行定制,从而更加高效地完成传输。

​

那在现代的计算系统当中, 大部分对数据传输率有比较高要求的设备都会自带 DMA 控制器, 而其他对数据传输率要求比较低的设备则可以共享系统中独立的 DMA 控制器。 另外这个独立的 DMA 控制器一般还会提供从内存到内存传送的服务。 那当我们编程时需要将内存中的一大块数据复制到内存的另一个区域的时候, 虽然不涉及输入输出,但是也可以享受到 DMA 带来的好处。 那当然也不是所有的输入输出设备都需要使用 DMA 的方式。 毕竟增加一个 DMA 控制器需要增加制造的成本, 而且 CPU 来配置 DMA 控制器以及进行后续的处理还是要靠执行程序来完成的,也都需要花时间。 如果要传输的数据量很小,性能反而会变差了。

那现在用 DMA 方式的这些设备不见得是这些工作 CPU 不愿意干,有可能是根本干不了。 比如说我们快递要送来的不是一千本书而是一万本书,而且非得一个小时内办完, 那你能干得了吗?非得叫搬家公司不可了,对不对? 但是不是说所有的事情都用 DMA 方式都能好好的解决的。 比如送来的不是一千本一万本书,而就是一本书, 那你也去叫一个搬家公司把这本书给你运来?那样就得不偿失了。 而且有时候你可能送来的根本不是书, 而是你的午饭,对吧,订了一份盒饭,难道你也叫一个搬家公司来给你收这个盒饭?那他们可能过了两个小时才来, 然后用他们规范的方法把你这顿饭给打包装箱送到他们的大货车, 然后运到你的楼下,再拆包,再给你送上来, 能赶上吃晚饭就不错了。

上次更新: 2025/5/9 14:55:39
905-外部中断的处理过程
简单聊聊计算机之中的时间

← 905-外部中断的处理过程 简单聊聊计算机之中的时间→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式