3.3.4 PCI设备进行DMA写时发生Cache命中
如果PCI设备访问的地址在某个CPU的Cache行中命中时,可能会出现三种情况。
第一种情况是命中的Cache行其状态为E,即Cache行中的数据与存储器中的数据一致;而第二种情况是命中的Cache行其状态为S。其中E位为1表示该数据在SMP处理器系统中,有且仅有一个CPU的Cache中具有数据副本;而S位为1表示在SMP处理器系统中,该数据至少在两个以上CPU的Cache中具有数据副本。
当Cache行状态为E时,这种情况比较容易处理。因为PCI设备(通过HOST主桥)写入存储器的信息比Cache行中的数据新,而且PCI设备在进行DMA写操作之前,存储器与Cache中数据一致,此时CPU仅需要在Snoop Phase使无效(Invalidate)这个Cache行,然后FSB总线事务将数据写入存储器即可。当然如果FSB总线事务可以将数据直接写入Cache,并将Cache行的状态更改为M,也可提高DMA写的效率,这种方式的实现难度较大,第3.3.5节将介绍这种优化方式。
Cache行状态为S时的处理情况与状态为E时的处理情况大同小异,PCI设备在进行写操作时也将数据直接写入主存储器,并使无效状态为S的Cache行。
第三种情况是命中的Cache行其状态为M(Modified),即Cache行中的数据与存储器的数据不一致,Cache行中保存最新的数据拷贝,主存储器中的部分数据无效。对于SMP系统,此时有且仅有一个CPU中的Cache行的状态为M,因为MESI协议规定存储器中的数据不能在多个CPU的Cache行中的状态为M。
我们假定一个处理器的Cache行长度为32B,即256b。当这个Cache行的状态为M时,表示这个Cache行的某个字节、双字、几个双字、或者整个Cache行中的数据比主存储器中含有的数据新。
假设HOST主桥访问的地址,在Snoop Phase,通过CPU进行总线监听后,发现其对应的Cache行状态为M。此时HOST主桥进行存储器写操作时,处理情况较为复杂,此时这些状态为M的数据需要回写到主存储器。
我们考虑如图3?8所示的实例。假定处理器的Cache使用回写(Write-Back)策略进行更新。在这个实例中,HOST主桥对存储器的某个地址进行写操作,而所有CPU通过FSB总线进行总线监听时发现,HOST主桥使用的这个目的地址在某个CPU的Cache行命中,此时这个CPU将置HITM#信号为0,并置HIT#信号为1,表示当前Cache行中含有的数据比存储器中含有的数据更新。

我们假设此时在Cache行中,阴影部分的数据比存储器中的数据新,而其他数据与存储器保持一致,即在这个Cache行中第0~3个双字的数据是当前处理器系统中最新的数据,而第4~7个双字中的数据与存储器保持一致。
如果PCI设备向存储器写的数据区域可以完全覆盖这些阴影部分,如对第0~5个双字进行写操作时,这种情况不难处理。此时CPU只需在总线监听阶段,将这个Cache行使无效,然后将数据写入存储器即可。因为完成这个存储器写操作之后,PCI设备写入的数据是最新的,而且这个最新的数据将完全覆盖在Cache行中阴影部分的数据,所以CPU只需要简单地将这个Cache行使无效即可。
然而PCI设备(HOST主桥)无法预先知道这些Cache行中的数据哪些是有效的,哪些是无效的,而仅知道命中了一个“被修改过”的Cache行,从而PCI设备(HOST主桥)无法保证能够对Cache行中有效数据进行覆盖。因此PCI设备对存储器进行写操作时,不能简单地使无效(Invalid)状态位为M的Cache行。
我们仍然以图3?8为例,考虑一个PCI设备将4个双字(第4~7个双字)的数据写入到一个存储器中,这4个双字所访问的数据在某个CPU的Cache行中命中,而且该Cache行的状态为M,而且这个Cache行的前4个双字曾被处理器修改过。
此时CPU对FSB总线监听时,不能简单将当前Cache行使无效,因为这个使无效操作将丢失阴影部分的有效数据。这个阴影部分中的有效数据并没有被PCI设备重新写入,因此在整个处理器系统中,这个阴影部分仍然包含最新的数据。将最新的数据丢弃显然是一种错误做法,将会导致处理器系统的崩溃。
为此HOST主桥需要专门处理这种情况,不同的HOST主桥采用了不同的方法处理这种情况,但无外乎以下三种方法。
(1) CPU进行总线监听后发现,HOST主桥访问的数据命中了一个状态位为M的Cache行,此时存储器控制器将通知HOST主桥重试或者延时处理,并暂时停止HOST主桥发起的这次存储器写操作。随后CPU将状态位为M的Cache行与存储器进行同步后,再使无效这个Cache行。之后HOST主桥在合适的时机,重新发起被HOST主桥要求重试的总线事务,此时CPU再次进行总线监听时不会再次出现Cache命中的情况,因此HOST主桥可以直接将数据写入存储器。许多HOST主桥使用这种方法处理PCI设备的存储器写总线事务。
(2) 首先HOST主桥将接收PCI设备进行DMA写的数据,并将这些数据放入存储器控制器的一个缓冲区中,同时结束PCI设备的存储器写总线事务。之后CPU进行总线监听,如果CPU发现HOST主桥访问的数据命中了一个状态位为M的Cache行时,则这个Cache行放入存储器控制器的另一个缓冲区后,使无效这个Cache行。最后存储器控制器将这两个缓冲区的数据合并然后统一写入到存储器中。
(3) HOST主桥并不结束当前PCI总线周期,而直接进行总线监听,如果CPU进行总线监听发现HOST主桥访问的数据命中了一个状态位为M的Cache行时,则将这个Cache行整体写入存储器控制器的缓冲区后使无效这个Cache行,之后HOST主桥开始从PCI设备接收数据,并将这些数据直接写入这个缓冲区中。最后HOST主桥结束PCI设备的存储器写总线周期,同时存储器控制器将这个缓冲区内的数据写入存储器。
以上这几种情况是PCI设备进行存储器写时,HOST主桥可能的处理情况,其中第1种方法最常用。而x86处理器使用的implicit writeback方式,与第2种方法基本类似。第3种方法与第2种方法并没有本质不同。
但是如果PCI设备对一个或者多个完整Cache行的存储器区域进行写操作时,上述过程显得多余。对完整Cache行进行写操作,可以保证将Cache行对应的存储器区域完全覆盖,此时Cache行中的数据在PCI设备完成这样的操作后,在处理器系统中将不再是最新的。PCI设备进行这样的存储器写操作时,可以直接将数据写入存储器,同时直接使无效状态为M的Cache行。
PCI总线使用存储器写并无效(Memory Write and Invalidate)总线事务,支持这种对一个完整Cache行进行的存储器写总线事务。PCI设备使用这种总线事务时,必须要事先知道当前处理器系统中CPU使用的Cache行大小,使用这种总线事务时,一次总线事务传递数据的大小必须以Cache行为单位对界。为此PCI设备必须使用配置寄存器Cache Line Size保存当前Cache行的大小,Cache Line Size寄存器在PCI配置空间的位置见图2?9。
存储器读(Memory Read)、存储器多行读(Memory Read Multiple)和存储器单行读(Memory Read Line)总线事务也是PCI总线中的重要总线事务,这些总线事务不仅和Cache有关,还和PCI总线的预读机制有关,本篇在第3.4.5节中重点介绍这些总线事务。
3.3.4 PCI设备进行DMA写时发生Cache命中的更多相关文章
- 3.3.5 DMA写时发生Cache命中的优化
在许多高性能处理器中,还提出了一些新的概念,以加速外设到存储器的DMA写过程.如Freescale的I/O Stashing和Intel的IOAT技术. 如图3?8所示,当设备进行存储器写时,如果可以 ...
- 3.3.2 PCI设备对不可Cache的存储器空间进行DMA读写
在x86处理器和PowerPC处理器中,PCI设备对"不可Cache的存储器空间"进行DMA读写的过程并不相同.其中PowerPC处理器对"不可Cache的存储器空间&q ...
- 3.2 PCI设备的数据传递
PCI设备的数据传递使用地址译码方式,当一个存储器读写总线事务到达PCI总线时,在这条总线上的所有PCI设备将进行地址译码,如果当前总线事务使用的地址在某个PCI设备的BAR空间中时,该PCI设备将使 ...
- 3.1 PCI设备BAR空间的初始化
在PCI Agent设备进行数据传送之前,系统软件需要初始化PCI Agent设备的BAR0~5寄存器和PCI桥的Base.Limit寄存器.系统软件使用DFS算法对PCI总线进行遍历时,完成这些寄存 ...
- 008 PCI设备BAR空间的初始化
一.PCI设备BAR空间的初始化 在PCI Agent设备进行数据传送之前,系统软件需要初始化PCI Agent设备的BAR0~5寄存器和PCI桥的Base.Limit寄存器.系统软件使用DFS算法对 ...
- 3.3.3 PCI设备对可Cache的存储器空间进行DMA读写
PCI设备向"可Cache的存储器空间"进行读操作的过程相对简单.对于x86处理器或者PowerPC处理器,如果访问的数据在Cache中命中,CPU会通知FSB总线,PCI设备所访 ...
- 2.3 PCI桥与PCI设备的配置空间
PCI设备都有独立的配置空间,HOST主桥通过配置读写总线事务访问这段空间.PCI总线规定了三种类型的PCI配置空间,分别是PCI Agent设备使用的配置空间,PCI桥使用的配置空间和Cardbus ...
- 利用WinDriver开发PCI设备驱动程序
摘要 WinDriver是Jungo公司出版的一个设备驱动程序开发组件,它可以大大加速PCI设备驱动程序的开发.作者在实际的项目中采用了WinDriver来开发设备驱动程序,取得了相当好的运行效果.从 ...
- PCI 设备详解一
2016-10-09 其实之前是简单学习过PCI设备的相关知识,但是总感觉 自己的理解很函数,很多东西说不清楚,正好今天接着写这篇文章自己重新梳理一下,文章想要分为三部分,首先介绍PCI设备硬件相关的 ...
随机推荐
- Java自学能学会吗?最新Java高级学习路线
就好像一千个人心中有一千个哈利波特一样,这个答案不绝对也不唯一,Java好学但自学的确阻力有些大,作为一门技术语言,它所蕴含的智慧绝对不是靠几本XX入门,XX框架之类的书所能概括,自学Java你要做好 ...
- HTML——filedset和legend标签
1.<filedset>定义围绕表单中元素的边框. 2.legend 元素表示作为 legend 元素的父元素的 fieldset 元素的其余内容的标题(caption). 使用案例: & ...
- Linux下查找大文件以及目录
转自:http://www.cnblogs.com/kerrycode/p/4391859.html 在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在 ...
- JAVA并发编程学习笔记------对象的可见性及发布逸出
一.非原子的64位操作: 当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值,这种安全性保证被称为最低安全性.最低安全性适用于绝大多数变量 ...
- 对List中每个对象元素按时间顺序排序
需求: 需要对List中的每个User按照birthday顺序排序,时间由小到大排列. 代码实现: import java.text.SimpleDateFormat; import java.uti ...
- 浅谈python中的闭包函数
闭包函数初探 通常我们定义函数都是这样定义的 def foo(): pass 其实在函数式编程中,函数里面还可以嵌套函数,如下面这样 def foo(): print("hello worl ...
- python生成随机图形验证码
使用python生成随机图片验证码,需要使用pillow模块 1.安装pillow模块 pip install pillow 2.pillow模块的基本使用 1.创建图片 from PIL impor ...
- python3,进程间的通信
本文来源于python 3.5版本的官方文档 multiprocessing模块为进程间通信提供了两种方法: 1.进程队列queue The Queue class is a near clone o ...
- 高通HAL层之bmp18x.cpp
继续上一个链接内容所讲:http://www.cnblogs.com/linhaostudy/p/8430583.html 下面bmp18x sensor为例进行分析. BMP18x Sensor: ...
- BZOJ 1434: [ZJOI2009]染色游戏
一开始想这不$SG$裸题...然后发现100组数据...然后发现连通块是任意的求$SG$貌似要暴力枚举.... 然后想了一下1维,手动打表,每次就是队当前所有异或后缀和求$mex$,好像就是$lowb ...