Cache&WriteBuffer学习总结

关于CacheWriteBuffer的原理可以查阅相关博客或书籍。这里我只想讨论哪种情况下不能使用CacheWriteBuffer,以及使用CacheWriteBuffer时给存储系统带来的一致性问题以及解决方法。

使用Cache通常需要存储器件具有下面的特性:

a.读操作将返回最后一次写入的内容,而且没有其它的副作用

b.写操作除了影响目标单元的内容外,没有其它的副作用

c.对同一目标单元的两次连续读取操作将得到相同的结果

d.对同一目标单元的两次连续写操作将会把第2次写操作的值写入目标单元,第1次写操作将没有意义

 

一.以下情况不能使用CacheWriteBuffer

由于在ARM系统中,IO操作通常被映射为存储器操作,IO的输出操作可以通过存储器写入操作实现:IO的输入操作可以通过存储器读取操作实现,这样IO空间就被映射成了存储器空间。例如:ARM芯片,对USARTSPI接口的读写是通过映射存储器操作来实现的,当读SPI的数据时,是读特定寄存器地址,当写SPI数据时,是写特定的寄存器地址。由于前后两次读取同一地址的内容不相同,故对于ARM芯片的SPIUSART不能使用Cache。因而对于存储器映射的IO空间的操作就不能使用Cache技术。

 

由于写缓冲技术可能推迟写操作,它同样不适合对于存储器映射的IO空间的操作。例如:当CPU向中断控制器的IO端口写ACK,清除当前中断请求标志位,并重新使能中断,如果使用了写缓冲技术,CPU的写操作将被先写入高速的缓冲区,高速的缓冲区可能在以后某个时间再将结果写到IO端口,这样就造成一种假象,似乎外设又发出了中断请求。

 

由于上述原因,通常MMU允许将某些地址空间设置成uncacheableunbufferableMMU页表中地址转换条目的CB位就是用于控制相应的存储空间的缓冲特性。其具体编码含义如下图所示:

 

程序设计中要注意以下几点:

1.       对于写回类型的Cache不能设置成Cached/Unbuffered.这是因为把它设置成Unbuffered是为了防止延迟存储访问操作的执行时间,而对于写回Cache,如果设置成Cached必然造成访问操作执行的延迟。

2.       对于存储器映射的IO空间要设置成Uncached/Unbuffered.原因已经在上面说了,如果在高级语言中访问存储器映射的IO空间时,还必须告诉编译器不要在优化时删掉有用的存储访问操作。在C语言中的作法是:使用关键字volatile声明存储器映射的IO空间来防止编译器在优化时删掉有用的存储访问。

3.       当程序的访问局部性很差时,应把存储区域设置成Uncached的。因为Cache引入的先提条件是建立在程序的时间局部性和空间局部性的。

 

 

二、存储系统的一致性问题

当存储系统中引入了Cache和写缓冲区时,同一地址单元的数据可能在系统中有多个副本,分别保存在cache中,写缓冲区中及主存中。如果系统采用了独立的数据cache和指令cache,同一地址单元的数据还有可能在数据cache和指令cache中有不同的版本。

当发生以下情况时,会产生不一致的情况:

1.       地址映射关系变化造成的数据不一致

情况1Cache

在虚拟地址到物理地址映射发系发生变化前,如果虚拟地址A1所在的数据块已经预取在Cache中,当地址映射关系发生变化后,如果虚拟地址A1所在的物理地址发生了变化,这时当CPU访问A1时,再使用Cache中的数据块将会得到错误的结果。

  

解决方法:

   在地址映射关系发生变化之前,执行下面操作: 

 如果数据Cache为写回类型的Cache,清空该数据Cache

  使指令Cache中相应的块无效

 

  如果数据Cache不是写回类型的Cache,则使数据Cache中相应的块无效

  使指令Cache中相应的块无效

 

   注意:为什么要分写回类型的Cache讨论,因为对于写回类型的Cache,无效并不使数据写回到主存中,必须用清空操作才行

 

  情况2WriteBuffer

当系统采用了写缓冲区时,在虚拟地址到物理地址映射关系发生变化前,如果CPU向虚拟地址A1的单元执行了写操作,该写操作已经将A1以及对应的数据写入到缓冲区中,当映射地址发生变化之后,如果虚拟地址A1所在的物理地址发生了变化,当写缓冲区将上面被延迟的写操作写到主存中时,使用的是变化后的物理地址,从而使写操作失败。

 

 解决方法:

1.       将相关的存储区域设置成非缓冲的。

或者

2. 在地址映射变化之前,将写缓冲区被延迟的写操作全部执行,即清空写缓冲区。

 

 注意:方法1是从整体上解决写缓冲区的问题。

 

2.       指令Cache的数据一致性问题

当系统中采用独立的数据Cache和指令Cache时,下面的情况会可能会造成指令不一致的情况。

情况:

  a.读取地址为A1的指令,从而包含该指令的数据块被预取到Cache中。

  b.A1在同一个数据块的地址为A2的存储单元的数据被修改。这个写操作可能影响数据Cache中,写缓冲区中和地址为A2的存储单元的内容,但不影响指令CacheA2的存储单元的内容。

  c.如果A2存放的是指令,当该指令执行的时候,将会发生指令不一致的情况

 

解决方法:在a,b之间插入如下的操作序列

对于使用统一的数据Cache和指令Cache的系统,不需要任何操作

 

对于使用独立的数据Cache和指令Cache的系统,使指令Cache内容无效

如果数据Cache是写回类型的,清空数据Cache,使数据写回主存

 

指令数据不一致的问题,通常发生在以下情况:当可执行文件加载到主存之后,在程序跳转到入口点开始处执行之前,先执行上述操作序列,以保证以下面指令的是新加载的可执行代码,而不是原来的旧代码。

 

3.       DMA造成的数据不一致问题

DMA操作会直接访问主存,而不会更新Cache和写缓冲中相应的内容,这样可能造成数据的不一致。

如果DMA从主存中读取的数据已经包含在Cache中,而且Cache中对应的数据已经被更新,这样DMA读到的将不是系统中最新的数据。同样,DMA写操作直接更新主存中的数据,如果该数据已经在Cache中,则Cache中的数据将会比主存中的数据“老”,也将造成数据的不一致。

 

解决方法:

DMA读主存之前,清空数据Cache和清空写缓冲区

DMA写主存之后,数据Cache中块使无效,或无效数据Cache

 

   最根本的解决方法:

   DMA访问的存储区域设置成Uncahced/Unbuffered

 

 

 

 2011-4-21

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值