CPU传统存取数据方式&DMA

前言

CPU 拷贝:

由 CPU 直接处理数据的传送,数据拷贝时会一直占用 CPU 的资源。

DMA 拷贝:

由 CPU 向DMA磁盘控制器下达指令,让 DMA 控制器来处理数据的传送,数据传送完毕再把信息反馈给 CPU,从而减轻了 CPU 资源的占有率。

上下文切换:

  • 当用户程序向内核发起系统调用时,CPU 将用户进程从用户态切换到内核态;

  • 当系统调用返回时,CPU 将用户进程从内核态切换回用户态。

网络 I/O

在这里插入图片描述

磁盘 I/O

在这里插入图片描述

读操作

当应用程序执行 read 系统调用读取一块数据的时候,如果这块数据已经存在于用户进程的页内存中,就直接从内存中读取数据。

如果数据不存在,则先将数据从磁盘加载数据到内核空间的读缓存(Read Buffer)中,再从读缓存拷贝到用户进程的页内存中。

read(file_fd, tmp_buf, len):基于传统的 I/O 读取方式,read 系统调用会触发 2 次上下文切换,1 次 DMA 拷贝和 1 次 CPU 拷贝。
发起数据读取的流程如下:

  1. 用户进程通过 read 函数向 Kernel 发起 System Call,上下文从 user space 切换为 kernel space。

  2. CPU 利用 DMA 控制器将数据从主存或硬盘拷贝到 kernel space 的读缓冲区(Read Buffer)。

  3. CPU 将读缓冲区(Read Buffer)中的数据拷贝到 user space 的用户缓冲区(User Buffer)。

  4. 上下文从 kernel space 切换回用户态(User Space),read 调用执行返回。

传统CPU存取数据

因为CPU 的工作速度和外设的工作速度差距太大,且外设格式种类繁多,无法直接存取,需要经过转换,因此CPU 不直接存取外设

基于上述原因,传统CPU 获取数据的步骤如下:

  1. CPU 将外设数据加载到内存(和CPU的处理速度最接近)

  2. CPU 检查 cache 是否有自己需要的数据(是否命中)

  3. 如果命中,直接返回数据;如未命中,继续从内存获取(这里暂时不考虑MMU)

  4. 返回数据

在这里插入图片描述

详细图示:
在这里插入图片描述

可以看到整个数据传输的过程:

  • 首先在用户进程进行read()系统调用的时候,操作系统会由用户态切换到内核态,然后由CPU向磁盘发起IO请求。
  • 磁盘在接收到IO请求以后,进行数据准备工作,将数据放在磁盘控制器缓冲区里。
  • 在数据准备工作完成以后,磁盘向CPU发出IO中断信号。
  • CPU收到中断信号后,会先将磁盘缓冲区中的文件copy到PageCache中,再将数据从PageCache中copy到用户缓冲区中。在这期间CPU是无法执行其他任务的。copy完成之后read()调用返回,操作系统刚从内核态切换回用户态。

故可以得知:在数据传输的过程,需要CPU亲自的去拷贝数据,并且在这期间CPU无法去做其他事情。简单的搬运几个字符没有问题,但是当处理大量数据的时候,如果每次都让CPU来搬运,显然忙不过来。

DMA

传统CPU 读取数据无论是将外设数据搬移到内存,还是从内存读取数据,都需要CPU 的参与。为了让 CPU 能够专注于处理手中事务,DMA 将负责数据的搬移工作。

DMA(Direct Memory Access)即直接存储器访问,借助内部的控制器来实现内存和外设之间的数据传输。有了DMA,CPU 可以专注于内存数据的存取;数据的搬运过程完全可以交由DMA硬件完成。有了DMA以后,不代表完全不需要CPU了,只是不会像中断那样频繁向CPU发送请求。

  • 开始传输时刻:DMA向CPU申请至少一个总线周期的占用时间来做数据传输工作
  • 结束传输时刻:DMA向CPU发送中断请求,请求CPU处理这些数据

在这里插入图片描述

详细图示:

在这里插入图片描述

  • 当有了DMA控制器以后,在进程向CPU发出read()调用以后,CPU向DMA控制器发起IO请求,然后DMA控制器再向磁盘发出IO请求。

  • 当磁盘接收到IO请求以后,会进行数据准备工作,将数据放到磁盘数据缓冲区当中。

  • 当磁盘的数据准备工作完成以后,不再向CPU发出中断信号,而是通知DMA控制器。

  • DMA控制器在接收到通知以后,将数据从磁盘控制器缓冲区中copy到内核缓冲区中。在这期间并不占用CPU,CPU可以处理其他的事情,执行其他的任务。

  • DMA控制器处理完之后向CPU发出中断信号,由CPU将数据从内核缓冲区copy至用户缓冲区中。copy完成之后read()调用返回,操作系统从内核态切换回用户态。

注意:起初的DMA控制器只在主板上,但是现在IO设备越来越多,数据传输的需求也不尽相同,所以现在每个IO设备中都有DMA控制器。

DMA工作模式

  • 直接模式
    DMA 直接进行从源地址到目的地址的数据传输。

  • FIFO 模式
    FIFO模式下,可以将要传输的多个数据(或字节)累计存储在FIFO缓冲器中,然后在FIFO缓冲器中设置存储阈值,当到达阈值时,FIFO会自动把所有存储的数据一次性的发送到目标地址。

DMA数据传输方式:

  • 单字传送(单次模式)
    DMA 请求获得批准后,CPU 让出一个总线周期用于字或字节的传送。结束后, DMA 控制器归还总线控制权,CPU 再重新判断下一个总线周期的总线控制权是 CPU 保留,还是继续响应一次新的 DMA 请求。这种方式称为单字传送方式,又称为周期挪用或周期窃取。
  • 块传送(突发模式)
    DMA 请求获得批准后,DMA 控制器掌管总线控制权,连续占用若干个总线周期,进行成组连续的批量传送,直到批量传送结束,才将总线的控制权交还给 CPU。这种方式称为成组连续传送方式

寻址模式:

  • 增量寻址:发送完数据后,继续发送下一个地址的数据,配合突发传输模式

  • 非增量寻址: 一发送完数据后,如果想要继续发送数据,需要更具软件配置的发送下一个数据的地址,再进行数据的传输

DMA 数据传输步骤

数据传输流程图:

在这里插入图片描述

一、准备阶段

CPU 会对 DMA 控制器和 IO 接口进行初始化,初始化的内容如下:

  • DMA 控制器初始化

    • 配置 DMA 内存缓冲区的首地址(即告诉DMA把数据放到哪)
    • 配置 DMA 传输方向(是向外设传数据,还是从外设读数据)
    • 配置 DMA 交换量(设置数据传输的上限)
  • 接口的初始化

    • I/O 设备的寻址信息

二、传输请求

  • 设备接口 => DMA 控制器
    设备接口向DMA控制器发送 “ DMA请求 ” ,即请求使用 DMA 进行数据传输

  • DMA 控制器 => CPU
    DMA 控制器向CPU申请 “ 总线占用 ”,DMA控制器和 CPU 只能有一个占用总线

  • CPU => DMA 控制器
    CPU 批准使用总线,此时CPU会让出一个或者多个总线周期用于数据传输。在DMA数据传输期间,CPU 停止访问内存,无法执行需要占用总线的指令。

  • DMA 控制器 => 设备接口
    DMA 批准设备请求,此时 DMA控制器将掌握总线控制权。如果是单字节传送,一个总线周期后,DMA归还总线控制权;如果是块传送,连续占用若干个总线周期后,DMA才会归还总线控制权。

三、数据传送
数据传送期间,DMA 控制器会向总线发送读/写命令、向 I/O 接口发响应信号。真正的数据交互是内存和设备接口,DMA 控制器只是负责控制整个数据传送流程。

四、善后处理
在初始化时,CPU 便指定了DMA的交换量,而且DMA 控制器内部有一个计数器,只有 DMA 控制器知道传送是否结束。当传送结束时,DMA控制器向CPU发送一个传输完成的中断,CPU重新接管总线的控制权。

注意:DMA 控制器并非只有在传输完成时才会发送中断,其实传输过半、传输错误也可以发送中断


DMA的双面性特点:对于CPU,DMA是外设;对于外设,DMA是控制器

为什么要使用DMA
第一,可以把比较固定的任务让DMA来做,可以减轻CPU负担,提高系统的效率;
第二,DMA具有一般CPU没有的高效操作,能够提高系统的吞吐率(IO 效率);

硬中断软中断

一、硬中断
由与系统相连的外设(比如网卡、硬盘)自动产生的,主要是用来通知操作系统系统外设状态的变化。

可屏蔽中断 ——当 CPU 接收到更高优先级的中断时,这些中断可以被延迟。

不可屏蔽中断 ——无法延迟这些中断。 CPU 应该立即考虑它们。

二、软中断
为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。

三、区别

  1. 引发对象:硬中断是由外设引发的,软中断是执行中断指令产生的,无需外部施加中断请求信号。
  2. 提供中断号:硬中断的中断号是由中断控制器提供的,软中断的中断号由指令直接指出,无需使用中断控制器。
  3. 耗时:硬中断处理程序要确保它能快速地完成任务,这样程序执行时才不会等待较长时间,称为上半部。软中断处理硬中断未完成的工作,是一种推后执行的机制,属于下半部。

硬中断(Hardware Interrupts)是由外部设备发起的,通常用于表示设备需要CPU的注意,例如I/O操作完成、定时器中断等。硬中断通常是可屏蔽的,这意味着在处理某个硬中断过程中,CPU可以禁止响应其他硬中断,以防止嵌套中断带来的问题。当然,也有一些特定情况下的硬中断是不可屏蔽的,例如非屏蔽中断(Non-Maskable Interrupt, NMI)。

软中断(Software Interrupts)则是由软件主动触发的,通常用于实现系统调用、异常处理等。软中断的可屏蔽性取决于具体实现和系统需求。在某些情况下,软中断可能是不可屏蔽的,以确保某些关键任务或异常处理能够得到优先执行。然而,在其他情况下,软中断可能是可以屏蔽的,以避免嵌套中断或提高系统性能。

学习博客

原文

图示博客

DMA 基础流程

cpu硬中断、软中断

硬中断是软中断区别

Epoll原理解析

深入理解 Linux 的 I/O 系统

零拷贝详细图解

零拷贝原理解析

零拷贝与DMA

DMA 直接内存访问技术-简书

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值