总线
计算机部件互连复杂:采取总线结构
数据传输类型
- 控制线:控制数据线和地址线的访问和使用
- 地址线:指定数据总线和地址I/0端口上数据来源或去向
- 数据线:在系统模块之间传输数据
类型:
- 芯片内部总线:连接芯片内部的各个部分(CPU中连接寄存器、ALU等部分)(小范围)
- 系统总线:连接CPU、存储器、IO控制器和其他功能设备(中范围)
- 通信总线:连接主机和I/O设备,或连接不同的计算机系统(大范围)
总线结构
- 数据线:数量决定了一次可以传输的数据的大小
- 地址线:数量决定了寻址空间的大小
- 控制线:控制对数据线和地址线的存取和使用(时钟、总线请求、总线允许、中断请求、存储器读、I/O写等)
总线:同时可以多个设备监听,只能一个设备发送数据。
发送数据的流程:
1、获取总线的使用权
2、通过总线传送数据
向另一个组件请求数据的流程
1、获得总线的使用权
2、通过总线向另一个设备发送请求,等待另一个设备发送数据
设计要素
用途、仲裁、时序、总线带宽、总线层次结构
用途
- 专用总线:始终只负责一项功能,或始终分配给特定的计算机组件
优点:高吞吐量,减少冲突;缺点:系统成本规模增加 - 复用总线:将同一线路用于多种用途
优点:布线数量少,减少成本规模;缺点:控制电路复杂,共享降低性能
仲裁
当多个设备需要与总线通信时,通过某种策略选择一个设备
平衡因素:
- 优先级:优先级高的设备优先被服务
- 公平性:优先级最低的设备不能一直被延迟
仲裁方案:
- 集中式:由仲裁器(arbiter)或总线控制器(bus controller)负责分配总线使用权(包含链式查询、计数器查询和独立请求)
- 分布式:每个设备都包含访问控制逻辑,各设备共同作用分享总线(包含自举式和冲突检测)
链式查询
所有设备串行连接,允许信号从优先级最高的设备下发到优先级最低的设备
- 某个设备发送请求,总线仲裁器收到请求,然后在总线不忙的情况下就会发送允许信号。这个允许信号会从一个设备经过另一个设备(串行)(通常都是先经过优先级高的设备)。如果期间有谁发送过请求,那么该设备就将总线设置为繁忙状态,防止允许信号进一步传递
优点:
- 确定优先级很简单
- 可以灵活添加设备
缺点:
- 不能保证公平性(处于优先级最低的设备可能永远都得不到请求的响应)
- 对电路故障敏感
- 限制总线的速度
计数器查询
将总线允许线替换为设备ID线
- 当总线仲裁器收到总线请求信号,并且总线空闲时,计数器开始计数,计数值通过设备ID线发送到各个部件。如果哪个部件的设备ID等于当前计数,就让它获得总线控制权。(计数方式可以改变)
优点:
- 可以设置不同初始计数(收到请求信号时从哪里开始计数)。这样就可以选择强调优先级(每次计数从1开始)还是强调公平性(每次计数从上一个计数完的计数开始循环)。
- 对电路故障不敏感
缺点:
- 需要添加设备ID线
- 需要解码和比较设备ID信号
- 限制总线的速度
独立请求
每个设备都有自己的总线请求线和总线允许线
- 设备请求可以通过总线请求线将请求信号发送给总线仲裁器,总线仲裁器决定哪个设备可以使用总线
优点:
- 快速响应
- 可编程的优先级
缺点:
- 复杂的控制逻辑
- 更多的控制线路
自举式
固定优先级,每个设备在其总线请求线上发送请求。每个设备需要自行判断当前请求中自己是否优先级最高。
- 所有设备都可以读取到其他比它更高优先级的设备的总线请求线。如果此时处于空闲状态,就判断是否有比自己优先级更高的设备的总线请求线处于激活状态。如果有,就需要等待它们的请求处理完毕;如果其他比自己优先级更高的设备的总线请求线都没有处于激活状态,那么就轮到自己获得总线控制器并激活繁忙状态。
冲突检测
一个设备想要使用总线时,如果总线空闲就直接使用总线。设备会检查是否发生冲突,如果此时发生总线冲突,就所有使用总线的设备停止传输数据,经过一个随机时间间隔后再次请求总线。(类似计网中报文碰撞时的回退算法)
时序
确定每个总线事务的开始和结束时间
- 一个总线事务:地址+数据+…+数据
类型:
- 同步时序:事件的发生由时钟决定
- 异步时序:一个事件的发生取决于前一个事件的发生(顺序)
- 半同步:半同步:同步时序和异步时序相结合
- 分离事务:分离事务:设备准备数据期间释放总线
同步时序
- 优点:更容易实现和测试
- 缺点:所有设备共享一个时钟,总线长度受到时钟偏差的限制
异步时序
握手策略:
三次握手:准备-确认-准备结束-确认结束
异步数据传输:
1、CPU 设置地址并设置 ReadReq 线 ➔ 存储器读取相应地址
2、存储器读取相应地址并设置 Ack 线 ➔ CPU 释放地址线和 ReadReq 线
3、CPU 释放地址线和 ReadReq 线 ➔ 存储器释放 Ack 线
4、存储器释放 Ack 线 ➔ 存储器将数据传到数据线
5、存储器将数据传到数据线并设置 DataRdy 线 ➔ CPU 读取数据
6、CPU 读取数据并设置 Ack 线 ➔ 存储器释放数据线和 DataRdy 线
7、存储器释放数据线和 dataRdy 线 ➔ CPU 释放 Ack 线
注意:这个过程中分为了两个部分,每个部分都是一个三次握手的过程。其中ACK线可以在不同时间属于不同的设备,最开始接收地址的时候ACK线由存储器设置,后面读取数据的时候ACK线由CPU设置。
4号过程就是中间传输数据的过程。理论上这段时间不使用总线,可以被其他设备使用
- 优点:可以灵活协调速度不同的设备
- 缺点:接口逻辑复杂,对噪声敏感(被误认为信号)
半同步时序
为了减少噪声的影响,在异步计时中使用时钟。
准备和响应信号在时钟上升沿有效。
结合了同步和异步定时的优点
分离事务
将一个总线事件分为两个过程
- 优点:增加总线利用率
- 缺点:增加每个总线事件的持续时间和系统复杂度
总线带宽和数据传输速率
总线带宽:总线的最大传输速率(不考虑总线仲裁、地址传输等因素)
数据传输速率:考虑地址宽度、握手等因素
总线宽度:组成总线的线数
- 数据总线越宽,一次传输的数据位数就越多
- 地址总线越宽,一次传输的地址位数就越多
注意:总线带宽指的就是物理上的二进制数据的传输,在进行传输时候(而不是准备传输的时候)的最大速度,不管你传输的是什么。而数据传输速率指的是有效数据的传输速度。它是需要准备的,需要包含准备的时间(地址传输、握手等)。它给人的表现就是我要传输这些数据内容,那么传输的过程需要包含传输地址等相关的准备,才可以真正进行有效数据的传输。我不管你实际传输的时候的带宽到底有多快,我只关心我最后传这些东西花了多久,把传输的有效数据量除以这个时间就是数据传输速率。
同步总线和异步总线的数据传输速率
例题1:假设同步总线的时钟周期为50ns,每次传输需要一个时钟周期,异步
总线每次握手需要40ns。两个总线都是32位宽,内存的数据准备时间为200ns。
当从存储器中读出一个32位的字时,计算两个总线的数据传输速率。
1、同步总线
-
数据传输时,需要先传输地址,然后需要内存数据准备,然后再传输数据
-
同步总线:没有三次握手的过程,当拿到地址后,就开始内存数据准备。准备完毕之后就开始传输数据。
-
因此,数据传输总时间为50+200+50=300ns,所以数据传输速率 = 32bit / (50 + 200 + 50)ns = 106.7Mbps
2、异步总线
-
数据传输时,也是需要经历传输地址-准备数据-传输数据的过程。但是不同之处在于:异步每次传输数据需要经历三次握手。而在传输地址的三次握手中,在第一次握手之后地址就已经准备好了,因此第一次握手之后就可以开始准备数据了。不过在准备完地址后还需要考虑结束第一次握手、以及开始第二次握手所需要的最短时间。准备完地址后,需要完成剩下的两次握手,然后从第一个三次握手(用于传输地址)到第二个三次握手(用于传输数据)之间还需要一次握手的时间。因此,从第一次准备完地址到第二个传输数据的三次握手之间的间隔至少也有相当于三次握手所需的时间间隔。所以我们需要判断准备数据的时间与进行三次握手的时间哪个更大,然后取更大的那个作为从准备完地址到准备完数据的时间。此处就是max(40ns* 3,200ns) = 200ns。然后准备完数据后又需要三次握手来传输数据。
-
因此,它一共数据传输时间为40(准备地址的第一次握手)+200(数据传输时间和三次握手之间的较大值)+120(传输数据的三次握手)=360ns。而数据传输速率即为32bit / (40 + 200 + 120)ns = 88.9Mbps
例题2:假设同步总线的时钟周期为50ns,每次传输需要一个时钟周期,异步总线每次握手需要40ns。两个总线都是32位宽,存储器的数据准备时间为230ns。当从存储器中读出一个32位的字时,计算两个总线的数据传输速率。
1、同步总线
-
与之前一样,需要经过传输地址、准备数据、传输数据的过程。但是由于同步总线是必须在时钟周期的整数倍的时候进行操作,不可以在一个时钟周期中间进行操作,因此存储器的准备时间230ns需要扩充至50的倍数,即250ns。
-
因此,数据传输时间为50+250+50=350ns,数据传输速率= 32bit / (50 + 250 + 50)ns = 91.4Mbps
2、异步总线
-
异步总线与之前的方法一样,先计算一次握手,然后是数据准备和三次握手。
-
因此,数据传输时间为40+230+120ns,数据传输速率= 32bit / (40 + 230 + 120)ns = 82.1Mbps
不同数据块大小的数据传输速率
例题3:假设系统具有以下特征:
- 它支持访问大小为4到16个字(每个字32位)的块
- 同步总线具有64位宽和200MHz时钟频率,需要1个时钟周期来传输
地址或64位数据 - 在两个总线事务之间有2个空闲时钟周期
- 内存访问时准备前4个字需要200ns,后面每4个字准备需要20ns
- 当前面的数据在总线上传输时,内存可以同时读取后面的数据
- 如果读取256个字,分别计算每次传输4个字和16个字时的数据传输速率、
传输时间和每秒总线事务数
每次传输4个字
一个总线事务即进行一次传输地址-准备数据-传输数据的过程。
先计算每次总线事务需要多少时间:
- 传输地址:1个时钟周期(5ns)
- 准备数据:200ns(这里的前4个字指的是每次访问时的前4个字,而不是全局的前4个字)
- 传输数据:10ns(每个周期64字即2个字,一次传输4个字需要两个时钟周期)
- 空闲:2ns
因此一次总线事务的时间为5+200+10+2 = 217ns,就可以计算出传输时间 = 2880 * 5ns = 14400ns,每秒总线事务数= (256 / 4) * (1s / 14400ns) = 4.44M,数据传输速率 = 256 * 32bit / 14400ns = 568.9Mbps
每次传输16个字
-
与每次传输4个字的区别在于:由于每次系统都支持访问大小为4-16个字的数据,在准备完4个字节的时候就可以直接发送,然后这个时候同时也可以继续传输数据。
-
所以,准备16个字的数据的时间为:第一次4个字需要200ns,在准备完4个字节后直接发送,同时准备后面四个字节。这个时候需要等到原来4个字节发送完并且新4个字节准备完,才可以进一步发送、准备。因此我们需要取出发送4字节的时间与准备4字节的时间之间的较大值。而这个过程需要持续3次(处理剩余12个字,每次能处理4个字,因此需要3次处理)。3次完毕后,就结束了数据传输。数据传输结束后还要记得把最后准备完的4个字节发送出去。
-
因此,一个总线事务中的数据传送的时间为:200+3×max(10,20) = 260ns,而一个总线事务整体的时间为5+260+10+10= 285ns,总传输时间为285×16 = 4560ns, 每秒总线事务数 = 16 * 1s / 4560ns = 3.51M,数据传输速率 = 256 * 32bit / 4560ns = 1796.5Mbps
提高总线的数据传输率
1、提高时钟频率(时钟周期数不变的情况下)
2、增加数据总线宽度(每次传输更多的数据)
- 成本:更多的总线线路
3、块传输(传输一次地址就传输一块数据)
- 成本:高复杂性
4、分离总线事务(减少总线空闲时间)
- 成本:复杂性高,增加每个事务的持续时间
5、分离地址线和数据线(同时传输地址和数据)
- 成本:更多的总线线路
总线层次结构
1、单总线层次结构
CPU、存储器和 I/O 模块都连接到一条系统总线
- 优点:简单,易于扩展
- 缺点:传输延迟会随着设备数、总线长度增大而增大;传输量过大时总线会成为瓶颈
2、双总线结构I
在CPU和存储器中间增加一个存储器总线
- 优点:增加CPU和存储器之间的传输效率,同时降低系统总线的负担
3、双总线结构II
将系统总线分为存储器总线、I/O 总线 和 IOP (input/output processer)
- 优点:优点:降低I/O对总线的负担
4、多总线结构I
增加一个 本地总线(local bus)来连接 CPU 和 cache
- 优点:分离了CPU和I/O的交互
5、多总线结构II
将系统总线分为存储器总线、I/O 总线和 DMA 总线
- 优点:增加 I/O 效率
6、多总线结构III
增加一个 高速 I/O 总线 来连接高速设备
- 优点:增加 I/O 交互效率