APP下载

DMA传输与Cache一致性分析

2014-07-24曹彦荣张锐

新媒体研究 2014年8期

曹彦荣 张锐

摘 要 介绍了Cache技术的基本原理,分析了DMA传输过程中存在Cache一致性问题,并介绍了几种解决Cache一致性问题方法,同时在实际应用中实现了安全的DMA传输设计。

关键词 DMA;Cache;数据一致性

中图分类号:TP3 文献标识码:A 文章编号:1671-7597(2014)08-0039-02

1 概述

在设计用于存储嵌入式系统的程序和数据的存储器时,常面临一个很难的选择,既希望有便宜而快速的存储器,但编译的存储器速度一般较慢,而快速的存储器一般不便宜。高速缓冲存储器Cache最早由Wilkes于1951年构想出来,为了弥合处理器与存储器之间速度差距而提出的。在计算机系统中,CPU执行所需的指令和数据都是保存在内存中的,但是CPU执行指令的速度要明显高于访问内存的速度。为了弥补主存速度的不足,在CPU和主存之间设置一个高速、小容量的缓冲存贮器(Cache),构成Cache—主存存贮层次。使之从CPU来看,速度接近于Cache的,容量却是主存的,CPU尽量不直接访问主存,只与高速Cache交换信息。

由于CPU访存具有相对的局部性,即CPU从主存取指令或取数据,在一定时间内,只是对主存局部地址区域的访问,因此将部分内存块预先暂存在Cache中,等到CPU需要访问时,大多时候直接访问Cache即可取得指令和数据,这样就可以很好的解决CPU执行速度和访存速度的冲突。

2 Cache工作原理

Cache的基本结构如图1所示,主要由Cache存储体、地址映射变换机构、替换机构几大模块组成。

图1 Cache的基本结构

2.1 Cache存储体

Cache存储体以块(或行)为单位与主存交换信息,为加速Cache与主存之间的调动,主存大多采用多体结构,且Cache访存的优先级最高。Cache存储体中的数据实际上是主存的一个副本。

2.2 地址映射变换机构

它将CPU送来的主存地址转换为Cache地址。由于主存和Cache的块大小相同,块内地址都是相对于块的起始地址的偏移量,因此地址变换主要是主存的块号。地址映射方法有很多,典型的方式有:全相联映射、直接映射、组相联映射和段相联映射等。

如果转换后的Cache块已与CPU欲访问的主存块建立了对应关系,即已命中,则CPU可直接访问Cache存储体。如果转换后的Cache块与CPU欲访问的主存块未建立对应关系,即不命中。此刻CPU在访问主存时,不仅将该字从主存取出,同时将它所在的主存块一并调入Cache,供CPU使用。将主存块调入Cache存储体时,如果Cache已被装满,就得采用替换策略。

2.3 替换机构

当Cache内容已满,无法接受来自主存块的信息时,就由Cache内的替换机构按一定的替换算法来确定应从Cache内移出哪个块返回主存,而把新的主存块调入Cache。常用的替换算法有RAND、FIFO、LFU、LRU和OPT等。

2.4 Cache的读写操作

Cache读操作过程比较简单,流程如图2所示。

图2 Cache读操作过程

Cache写操作比较复杂,因为对Cache块内写入的信息,必须与被映射的主存块内的信息完全一致。当程序运行过程中需对某个单元进行写操作时,会出现Cache一致性问题,即可能存在Cache中的数据和内存中的数据不一致的现象。一般的解决方法有两种:写直达法和写回法。

写直达法,每次向Cache写入时,同时也向主存写入。这样会增加访存次数,但作为CPU的读写操作,Cache和内存数据是一致的。

写回法,数据每次只是暂时写入Cache中,并用标志标明,直到该块被替换出Cache时,才写入主存,优势是速度快。

2.5 Cache的改进

Cache刚出现时,典型系统只有一个缓存,但为了进一步提高CPU读写效率,提出了分立Cache和多级Cache。

多级Cache,指CPU和内存之间设置不止一级的Cache。Cache的目的是,为了给出逼近最快存储器的速度,同时以较便宜的半导体存储器的价格提供一个大的存储器容量。多级Cache也就进一步加速了存储器访问速度。

分立Cache,指将指令和数据分开,分别存在指令Cache和数据Cache中。主要基于两点考虑:一是指令和数据的特性不一样,指令一般只需读取,不需对其进行写操作,而数据要进行读和写操作;二是为了指令执行的控制,将指令和数据分开更易于实现超前控制或指令流水线控制。

3 DMA传输Cache一致性问题

DMA传输方式是一种高效的数据传送方式,它采用专门的硬件(DMA控制器)来控制数据传送,数据在外部设备(包括IO设备、硬盘等)和主存储器之间、或者主存储器与主存储器之间直接进行传送,无需经过CPU,并且也不需要CPU的干预。这样,外设通过DMA控制器可以直接访问主存储器,与此同时,CPU可以继续执行程序,从存储器中读取指令或读写数据。除了CPU写操作时会遇到Cache数据和内存数据不一致的情况,DMA传输同样也带来Cache数据和内存数据不一致的问题。

在没有DMA传输的系统中,只有CPU修改内存数据,采用写直达法或写回法使得CPU读写时Cache对于程序员是透明的,数据始终一致。但是加入DMA控制器之后情况就变得复杂了,如图3所示,假设DMA控制器将IO设备中的数据传送至内存,这时内存中变量A已经更新,但Cache中变量A的值不变。将来的某个时刻,CPU要访问变量A,明明A的值已经更新,却命中Cache获取了旧值,发生了数据不一致现象。endprint

图3 Cache一致性问题

解决数据传输时的Cache一致性主要有以下几个方法。

1)采用按字传输。在内存和外设之间传输数据时,不用DMA方式,采取按字传输,典型的做法就是调用memcpy()函数。配置好Cache模式(写直达法或写回法),Cache对程序员来说是透明的,所有访问也是安全的。该方案属于PIO方式,缺点是,首先,传输的效率不如DMA方式快;其次,整个传输过程需要CPU全程参与,CPU无法执行其它任务,对系统性能有很大影响。

2)关闭数据Cache。关闭系统的数据Cache,只使能指令Cache,这也是一种很有效的做法。CPU在读写数据时,都直接从内存读取或直接写入内存,数据不一致的现象自然也就消除了。由此带来的缺点也显而易见,CPU执行指令的速度和访存速度严重不匹配,导致系统性能很差劲。

3)不可Cache内存的DMA传输。在操作系统启动时,会将内存配置成可Cache内存和不可Cache内存两种。前者可以映射到Cache中,后者不可以。CPU每次读写不可Cache内存时,都会发生Cache不命中,进而直接访问内存,当然这块内存也无法在Cache中形成副本。对于不可Cache内存,在DMA传输前后不会出现Cache一致性问题,因此不可Cache内存也被称为Cache-safe内存。VxWorks操作系统中可以使用cacheDmaMalloc()函数来分配不可Cache内存。

4)可Cache内存的DMA传输。使用可Cache内存进行DMA传输之前,如果源地址是内存地址,先调用cacheFlush()函数将Cache中的数据刷新到内存中,保证DMA传输的是Cache中的新值,而不是内存中的旧值。DMA传输完毕之后,如果目的地址是内存地址,需要调用cacheInvalidate()函数将Cache中的数据置为无效,保证将来CPU访问数据时,获取的是内存中的新值,而不是Cache中的旧值。

4 安全的DMA传输设计

在CPU与外设通过PCI总线互联的某存储器模块上,需要进行DMA传输设计,方法1和2的总体性能都不高,不宜采用。因为系统发起读写请求时,极可能使用不可Cache内存作为数据缓冲区,无法采用方法3,所以只能采用方法4。

对于Cache操作是以块(Cache行)为单位的,尽管操作系统中提供了刷新Cache和Cache无效的程序,但还是存在边界问题和对齐问题。如PowerPC处理器以32字节为一个Cache行,调用cacheFlush()和cacheInvalidate()函数只能保证按Cache行对齐时的数据一致性,与现实情况还有一定的差异。

安全的DMA传输通过以下几个方面来保证。

1)DMA控制器要求进行DMA传输的源地址、目的地址和传送长度都必须按8字节对齐。所以硬件设计上,PCI(PCIe设备兼容PCI)空间的数据缓冲区起始地址按8字节对齐,同时设备支持8字节对齐的Burst访问。

2)通过文件系统的配置修改,使得内存中数据缓冲页的起始地址按照8字节地址对齐。

3)在启动DMA传送前和结束DMA传送后,对于内存数据缓冲页中32字节对齐部分调用cacheFlush()刷新或者调用cacheInvalidate()无效,并且对内存数据缓冲页前后非32字节对齐处做Cache一致性的保护处理,如图4所示。

图4 安全的DMA传输

参考文献

[1]郑纬民,汤志忠.计算机系统结构(第二版)[M].北京:清华大学出版社,1998.

[2]张晨曦,等.计算机体系结构[M].北京:高等教育出版社,2000.

[3]武杨.高速缓冲存储器Cache设计的关键技术分析[J].中国科技信息,2006(7).

[4]胡彧,柴华.Cache一致性机制及其相关研究[J].科技情报开发与经济,2008(17).

作者简介

曹彦荣(1983-),男,山西临汾人,工程师,本科,研究方向:计算机硬件设计。endprint

图3 Cache一致性问题

解决数据传输时的Cache一致性主要有以下几个方法。

1)采用按字传输。在内存和外设之间传输数据时,不用DMA方式,采取按字传输,典型的做法就是调用memcpy()函数。配置好Cache模式(写直达法或写回法),Cache对程序员来说是透明的,所有访问也是安全的。该方案属于PIO方式,缺点是,首先,传输的效率不如DMA方式快;其次,整个传输过程需要CPU全程参与,CPU无法执行其它任务,对系统性能有很大影响。

2)关闭数据Cache。关闭系统的数据Cache,只使能指令Cache,这也是一种很有效的做法。CPU在读写数据时,都直接从内存读取或直接写入内存,数据不一致的现象自然也就消除了。由此带来的缺点也显而易见,CPU执行指令的速度和访存速度严重不匹配,导致系统性能很差劲。

3)不可Cache内存的DMA传输。在操作系统启动时,会将内存配置成可Cache内存和不可Cache内存两种。前者可以映射到Cache中,后者不可以。CPU每次读写不可Cache内存时,都会发生Cache不命中,进而直接访问内存,当然这块内存也无法在Cache中形成副本。对于不可Cache内存,在DMA传输前后不会出现Cache一致性问题,因此不可Cache内存也被称为Cache-safe内存。VxWorks操作系统中可以使用cacheDmaMalloc()函数来分配不可Cache内存。

4)可Cache内存的DMA传输。使用可Cache内存进行DMA传输之前,如果源地址是内存地址,先调用cacheFlush()函数将Cache中的数据刷新到内存中,保证DMA传输的是Cache中的新值,而不是内存中的旧值。DMA传输完毕之后,如果目的地址是内存地址,需要调用cacheInvalidate()函数将Cache中的数据置为无效,保证将来CPU访问数据时,获取的是内存中的新值,而不是Cache中的旧值。

4 安全的DMA传输设计

在CPU与外设通过PCI总线互联的某存储器模块上,需要进行DMA传输设计,方法1和2的总体性能都不高,不宜采用。因为系统发起读写请求时,极可能使用不可Cache内存作为数据缓冲区,无法采用方法3,所以只能采用方法4。

对于Cache操作是以块(Cache行)为单位的,尽管操作系统中提供了刷新Cache和Cache无效的程序,但还是存在边界问题和对齐问题。如PowerPC处理器以32字节为一个Cache行,调用cacheFlush()和cacheInvalidate()函数只能保证按Cache行对齐时的数据一致性,与现实情况还有一定的差异。

安全的DMA传输通过以下几个方面来保证。

1)DMA控制器要求进行DMA传输的源地址、目的地址和传送长度都必须按8字节对齐。所以硬件设计上,PCI(PCIe设备兼容PCI)空间的数据缓冲区起始地址按8字节对齐,同时设备支持8字节对齐的Burst访问。

2)通过文件系统的配置修改,使得内存中数据缓冲页的起始地址按照8字节地址对齐。

3)在启动DMA传送前和结束DMA传送后,对于内存数据缓冲页中32字节对齐部分调用cacheFlush()刷新或者调用cacheInvalidate()无效,并且对内存数据缓冲页前后非32字节对齐处做Cache一致性的保护处理,如图4所示。

图4 安全的DMA传输

参考文献

[1]郑纬民,汤志忠.计算机系统结构(第二版)[M].北京:清华大学出版社,1998.

[2]张晨曦,等.计算机体系结构[M].北京:高等教育出版社,2000.

[3]武杨.高速缓冲存储器Cache设计的关键技术分析[J].中国科技信息,2006(7).

[4]胡彧,柴华.Cache一致性机制及其相关研究[J].科技情报开发与经济,2008(17).

作者简介

曹彦荣(1983-),男,山西临汾人,工程师,本科,研究方向:计算机硬件设计。endprint

图3 Cache一致性问题

解决数据传输时的Cache一致性主要有以下几个方法。

1)采用按字传输。在内存和外设之间传输数据时,不用DMA方式,采取按字传输,典型的做法就是调用memcpy()函数。配置好Cache模式(写直达法或写回法),Cache对程序员来说是透明的,所有访问也是安全的。该方案属于PIO方式,缺点是,首先,传输的效率不如DMA方式快;其次,整个传输过程需要CPU全程参与,CPU无法执行其它任务,对系统性能有很大影响。

2)关闭数据Cache。关闭系统的数据Cache,只使能指令Cache,这也是一种很有效的做法。CPU在读写数据时,都直接从内存读取或直接写入内存,数据不一致的现象自然也就消除了。由此带来的缺点也显而易见,CPU执行指令的速度和访存速度严重不匹配,导致系统性能很差劲。

3)不可Cache内存的DMA传输。在操作系统启动时,会将内存配置成可Cache内存和不可Cache内存两种。前者可以映射到Cache中,后者不可以。CPU每次读写不可Cache内存时,都会发生Cache不命中,进而直接访问内存,当然这块内存也无法在Cache中形成副本。对于不可Cache内存,在DMA传输前后不会出现Cache一致性问题,因此不可Cache内存也被称为Cache-safe内存。VxWorks操作系统中可以使用cacheDmaMalloc()函数来分配不可Cache内存。

4)可Cache内存的DMA传输。使用可Cache内存进行DMA传输之前,如果源地址是内存地址,先调用cacheFlush()函数将Cache中的数据刷新到内存中,保证DMA传输的是Cache中的新值,而不是内存中的旧值。DMA传输完毕之后,如果目的地址是内存地址,需要调用cacheInvalidate()函数将Cache中的数据置为无效,保证将来CPU访问数据时,获取的是内存中的新值,而不是Cache中的旧值。

4 安全的DMA传输设计

在CPU与外设通过PCI总线互联的某存储器模块上,需要进行DMA传输设计,方法1和2的总体性能都不高,不宜采用。因为系统发起读写请求时,极可能使用不可Cache内存作为数据缓冲区,无法采用方法3,所以只能采用方法4。

对于Cache操作是以块(Cache行)为单位的,尽管操作系统中提供了刷新Cache和Cache无效的程序,但还是存在边界问题和对齐问题。如PowerPC处理器以32字节为一个Cache行,调用cacheFlush()和cacheInvalidate()函数只能保证按Cache行对齐时的数据一致性,与现实情况还有一定的差异。

安全的DMA传输通过以下几个方面来保证。

1)DMA控制器要求进行DMA传输的源地址、目的地址和传送长度都必须按8字节对齐。所以硬件设计上,PCI(PCIe设备兼容PCI)空间的数据缓冲区起始地址按8字节对齐,同时设备支持8字节对齐的Burst访问。

2)通过文件系统的配置修改,使得内存中数据缓冲页的起始地址按照8字节地址对齐。

3)在启动DMA传送前和结束DMA传送后,对于内存数据缓冲页中32字节对齐部分调用cacheFlush()刷新或者调用cacheInvalidate()无效,并且对内存数据缓冲页前后非32字节对齐处做Cache一致性的保护处理,如图4所示。

图4 安全的DMA传输

参考文献

[1]郑纬民,汤志忠.计算机系统结构(第二版)[M].北京:清华大学出版社,1998.

[2]张晨曦,等.计算机体系结构[M].北京:高等教育出版社,2000.

[3]武杨.高速缓冲存储器Cache设计的关键技术分析[J].中国科技信息,2006(7).

[4]胡彧,柴华.Cache一致性机制及其相关研究[J].科技情报开发与经济,2008(17).

作者简介

曹彦荣(1983-),男,山西临汾人,工程师,本科,研究方向:计算机硬件设计。endprint