DMA和Cache的一致性
哈喽,最近接触了DMA并且还有一致性的问题,来重新回忆一下Cache和DMA吧!
DMA(Direct Memory Access)直接内存访问,其传输过程中是不需要CPU干预的,可以直接从内存中读写数据。为什么要有DMA呢,假设CPU要对数据进行迁移,从内存x搬移到内存y中,首先CPU要把内存x中的数据搬移到通用寄存器里,然后再把数据搬移到内存y中,同时CPU作为一个大忙人,万一来个中断,有可能就会停下去做更紧急的事情。因此DMA来了,它可以操作总线,直接从内存x搬移数据到内存y,DMA启动后,并不会被打断,因此DMA在效率上比CPU要快的很多,CPU只需要告诉DMA从哪里搬到哪里就行。
那么问题来了,在实际应用过程中,有cache的存在,就会出现数据不一致的情况下,下图是3级缓存cache,本文对cache并不做过多的介绍,只需要知道CPU的速度很快,如果CPU直接访问内存进行数据或指令的读取速度会比使用cache慢了100倍,所有如果有cache的存在,计算性能会有很大的提升。
事实上,cache和DMA的产生解决了大问题,但又遗留了小问题,需要解决数据同步一致性问题。一般来说,DMA获得的数据和cache中的数据不一致主要有两方面的原因:
- DMA直接操作系统总线来读写内存地址,而CPU并不感知。
- DMA修改的内存地址,在CPU的cache中有缓存,但是CPU并不知道内存数据被修改了,CPU依然去访问cache的旧数据,导致Cache一致性问题。
那么如何进行DMA和cache一致性问题的解决呢
- 使用硬件进行一致性方案的解决,但是需要SOC中支持CCI IP
- 使用non-cacheable的内存来进行DMA传输
- 软件干预解决一致性
下图是CPU cache 和 DMA的简单流程
主要有两个场景,1)从buffer从内存中获取数据2)CPU从 内存中获取数据
从内存到buffer
在这种情况下,一般是CPU处理完了数据,需要返回给外设buffer中,那么在DMA搬移内存中的数据之前,内存中的数据可能并不是最新的,cache中可能缓存了最新的数据,那么就需要cache clean/flush 操作,将cache中的数据写到内存中,然后DMA再进行数据的搬移,将数据搬移到外设buffer中。
从buffer到内存
此时,外设buffer中产生了新的数据,那么就需要DMA将其写到内存中,然后CPU就可以读到最新的数据,那么该如何进行操作呢,DMA在传输数据之前,cache里的数据就是旧的无效数据,我们需要invalid,然后在启动DMA进行数据的更新。
简单来说,就是CPU产生新数据需要flush cache,CPU获取新数据需要invalid cache。
则移山填海之难,
终有成功之日!
——孙文