直接内存访问DMA

DMA(Direct Memory Access)允许硬件子系统不通过CPU直接访问内存,减少CPU的IO负担,提高系统效率。博客详细介绍了DMA的概念、类型(第三方DMA、总线控制)、操作模式(突发模式、循环挪用、透明模式)以及缓存一致性问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

翻译并提取自维基百科:https://en.wikipedia.org/wiki/Direct_memory_access

概念

DMA(Direct Memory Access)是一种硬件体系特性,它允许某些硬件子系统不通过CPU就直接访问随机访问内存(RMA)。它是一种系统特性,而非指定的某种硬件或者软件,而为了实现这种特性,可能需要用到专门的DMA外设(第三方DMA),也可以直接通过系统机制来实现(第一方DMA)。为什么要提供DMA机制呢?由于内存访问的操作通常频繁发生,如果没有DMA机制,所有的硬件都要等到CPU调度来访问RMA的话,那么CPU的时间将会被大量的IO操作所占据,从而无法为其他的程序提供服务。而采用了DMA机制之后,CPU只需要启动一个控制器(DMA Controller),在控制器自行调度硬件内存访问的同时CPU可以执行其他的工作,而DMA Controller在工作完毕后发送一个中断给CPU,通知其内存调度已经完成。这一机制使得CPU的时间片可以用在更加紧急的任务上,而无需处理相对较为缓慢的数据传输工作,也可以让CPU无法空闲的情况下硬件子系统仍旧可以访问物理内存。

拥有DMA通道的硬件系统,在数据传输、硬件存取方面的CPU开销比无DMA通道的硬件系统要小得多得多。启用DMA机制后,系统中可以真正并发的进行计算操作与数据传输。

DMA不仅仅可以用在硬件设备对于内存空间的访问上,还可以用于内存之间的操作,如内存拷贝、内存移动、碎片整理等,以及硬件到硬件之间的数据传输操作。


DMA类型

第三方DMA

通常我们说DMA,都指的是第三方DMA。这种类型的DMA实现使用了一个DMA Controller。DMA Controller通过生成内存地址并启动存储器读写周期来提供内存访问操作。DMA Controller包含了一些可以被CPU读写的硬件寄存器,比如内存地址寄存器、字节计数寄存器、以及一个或多个的控制寄存器等。这些寄存器用于指定数据传输的源地址、目的地址、传输方向(读设备或写设备)、传输单元的大小、以及根据DMA Controller的特性提供的在一个突发性读写中的字节计数。

当需要完成一项IO操作的时候,CPU将初始化DMA Controller,并且将需要传输的字节数量及内存地址提供给DMA Controller,随后通知外围设备(即需要执行IO操作的设备)可以开始数据传输了。随后的IO操作将由DMA Controller来执行,DMA Controller向系统内存提供地址以及读写控制行,然后每当有一个字节可以被读写时,DMA Controller执行这项操作并且递增其内部地址寄存器,直到整块数据被传输完成。

总线控制

第一方DMA,即总线主控系统。在这种系统中,CPU与外围设备都被赋予了内存总线的控制权。当外围设备拥有了总线控制权以后,外围设备就可以在没有CPU参与的情况下对系统内存进行IO操作,直接根据自身需要向系统内存提供内存地址以及控制信号。但在这种模式下,必须采取一些措施使得CPU处于保持状态,避免总线竞争的发生。

传输类型

DMA传输可以是一字节一字节进行的,当然也可以在突发模式下提供一次性完全的数据传输操作。在第一种模式下,CPU可以在内存总线的空闲期访问内存空间——这被称作为循环挪用(cycle stealing),因为CPU和DMA Controller(第三方DMA)或者总线控制系统(第一方DMA)会竞争内存总线的控制权。而在第二种模式下,在DMA传输数据时,CPU可能被置为保持状态,等待数以百计或千计的字节被传输完成后才能获取内存总线的控制权。当内存存储周期比处理器周期快的多的时候,可能产生一种交错的DMA周期,即DMA使用内存总线时CPU不可以使用。


操作模式

突发模式

该模式下,整块数据将被按顺序的连续传输。当DMA Controller从CPU获取了内存总线的访问控制权后,在整块数据被传输完成之前DMA Controller都不会将控制权移交回CPU,使得CPU在相对较长的时期无法使用内存访问。这种模式也叫“块传输模式”。该模式同样也被用于停止一些不必要的数据。

循环挪用模式

该模式被用于:当CPU不应该在整块数据传输完成之前被禁用总线的情况下使用。在这种模式下,DMA Controller使用和突发模式中一样的方式获取内存总线的控制权——使用BR(Bus Request)和BG(Bus Grant)两个控制信号。但在这种模式下,当一个字节被传输完成后,CPU通过发送BG信号终止DMA Controller对内存总线的控制权,然后DMA Controller再通过BR信号来申请新一轮的控制权用于传输下一个字节。在不断的获取和失去内存总线的控制权的情况下,DMA Controller基本上在交错的发送信号和传输数据。一方面,这种模式下的数据传输速度无法像突发模式下那么快,但是另一方面看,这种模式下的CPU等待获取内存总线控制权的空闲时间也无需像突发模式下的那么久。该模式对于那些需要实时监控数据的控制器很有效。

透明模式

透明模式下传输整块数据所花费的时间最久,但是它在整体的系统性能上也是最好的。在这种模式下,DMA Controller只在CPU正在执行那些不需要用到系统总线的操作时才会执行数据传输。该模式的主要优点在于数据传输时CPU无需中断自身的任务以等待获取总线控制权,并且DMA也在使用总线时更加自由。但是该模式的限制在于硬件必须知道CPU什么时候不需要使用总线,这一点上的实现较为复杂。


缓存一致性问题

DMA机制可能会导致缓存一致性的问题。比如当系统中配备了缓存,并且外部存储可以被外围设备通过DMA直接访问时,CPU读取了内存中的一个数据X,此时CPU将X置于缓存中以提高存储速度,这个时候CPU对于X的修改将写在缓存中而不是直接写到实际内存中去。假如在缓存没有被写回(flush)时,外围设备通过DMA读取了X,这个X的值将是一个旧值,与真实的、被CPU处理过的值不一致。同样当外围设备通过DMA修改了X的时候,CPU并不会更新缓存中的X副本(因为根本就不知道被改写了),因此CPU对于X的后续计算都建立在一个过期的旧值上,也就导致了数据错误。

现在有两种系统设计方案用于解决这个问题:一、缓存一致性系统通过在硬件设备中实现一种方法,当出现外部数据读写时,硬件设备发送一个信号至缓存控制器,使得缓存控制器在DMA写数据时将被缓存的数据置为无效,或者在DMA读数据时将缓存中的数据写回到实际内存中去。二、缓存不一致系统将这个问题留给了软件系统解决。这种情况下,操作系统必须代替硬件完成一致性保障工作,在DMA读数据时保证缓存被写回,并且在DMA写数据时保证将缓存中的值置为无效,并且在这个期间,操作系统还需要保证没有任何线程会对该区域的内存数据进行读写操作。第二种方法为DMA引入了一些额外的开销,因为所以的硬件设备都需要使用一个循环来使得每一个缓存行无效。

同时,还存在更加混杂的方式,如采用了多级缓存的系统中,L2缓存被硬件设备保证了一致性,但L1缓存(通常在CPU上使用)由于被软件管理,还需要额外的开销来保证一致性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值