草庐IT

什么是计算机中的高速公路-总线?

xiaoniuhululu 2023-03-28 原文

作者:小牛呼噜噜 | https://xiaoniuhululu.com
计算机内功、JAVA底层、面试、职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜

大家好,我是呼噜噜,在之前的文章计算机的基本组成是什么样子的中,我们知道了现代计算机还是沿用了冯·诺依曼计算机架构,分别是运算器、控制器、存储器、输入设备、输出设备。那么计算机是如何让这些部件相互通信,传递数据的?其实计算机的各个部件就是依赖总线系统,相互协调,连接成一个整体,本文就来详细聊聊总线系统

总线是什么?

总线是贯穿整个系统的是一组电子管道,是连接各个部件的信息传输线,是各个部件共享的传输介质,称作总线,它携带信息字节并负责在各个计算机部件间传递

在总线出现之前,我们计算机各个设备都是各自单独互相通信的,如果有n个设备,由于他们都需各自单独互相通信,其中一个设备需要和其他n-1个设备通信,那系统的复杂度为N^2

为了降低系统复杂度,工程师们想到了一个办法,在计算机中设计一个公共的线路,其他的各个设备都不需要各自单独互相通信,只需和这个公共线路通信,将指令和数据传送给线路,线路代为转递,这样系统复杂度就可以降为了N

这条线路就像一个高速公路,我们把它称为总线(Bus),总线除了降低了系统复杂性,还提供了一个标准化的数据交换方式,便于接口设计,各个硬件按照总线的标准实现接口,而无需考虑对方接口或总线的工作原理,有利于各个部件模块化设计。这样的设计下,注册在总线上的各个模块就是低耦合的,方便未来代码的维护或者扩展。

常见总线类型有哪些?

计算机系统中的总线,按功能可以划分为以下 3 类:

  1. 片内总线。片内总线顾名思义就是芯片内部的总线,它是CPU芯片内部寄存器与寄存器之间、寄存器与算术逻辑部件ALU之间、ALU与控制部件之间 传输数据所用的公共连接线称为 片内总线
  2. 通信总线。通信总线是在计算机系统之间、计算机系统与外部设备(如远程通信设备、测试设备)之间传送信息的总线,通信总线也称外部总线
  3. 系统总线。系统总线是计算机系统内各功能部件(CPU、主存、I/O接口)之间互相连接的总线。按系统总线传输信息内容的不同,又可以分为3 种:数据总线、地址总线和控制总线。下文我们将具体看一下这三类总线

内部总线:查阅各种资料发现各种说法都有,比如维基百科的上是指南桥芯片与北桥芯片之间的连线;国内有的资料说芯片内部的总线即片内总线为内部总线,有的说是微机中各插件板与系统板之间的总线等等,概念太乱了,本文就不阐述了,感兴趣的话可以留言讨论

总线的串行和并行的区别?

在详细介绍数据总线、地址总线和控制总线之前,我们还得先了解一下总线的串行和并行的区别

数据传输格式可将总线划分为并行总线串行总线

  1. 串行总线,由于只需一条传输线就能实现数据的收发
  2. 并行总线,就是数据传输有多根线,这样就可以一次发送多位的数据。

同样一个字节数据(8位),串行通信要分8次由低位到高位按顺序一位位地传送,而并行通信由于有8根线路,可以一次把8位数据传送过去。通俗点讲,串行如同开一辆车分八次把货物运走,并行就是同时开8辆车,一口气把货物运走。

在早期计算机中,计算机的主频比较低,串行总线传输效率比并行总线慢,毕竟并行一次可以传多位,肯定比串行快。但并行总线也有一些问题:

  • 传输线数量多,意味着接口就需要很多针脚,占用更多的布线空间。老式计算机里的并行接口做得很大,接线比较宽,针脚非常多。
  • 并行的链路越多,对数据传输的干扰就越强,因此并行总线需要加强抗干扰的能力,不然传输过程中数据就可能被损坏
  • 如果并行传输过程中数据中有一位故障了,就需要重新对齐数据再次传输

但随着计算机和材料学的高速发展,计算机的主频越来越高,并行的信号线之间会产生严重干扰,对每条线等长的要求也越高,反过来会限制计算机主频的提升,而串行总线则没有这个问题,因此像现在USB接口,让串行传输浴火重生

虽然串行每次传输的数据少,但它可以不断提高工作频率来提高传输速度,最终超过并行总线传输效率

再有如果传输过程中有一位的数据出现异常,并行总线就需要重新对齐数据再传输过去。而串行总线如果一位数据出错了,只需要重新传输一次就好了,由于串行总线频率高,很快就可以把错误数据重新传输过去。串行总线成本较低,还可以节约计算机硬件的布线空间

使用串行总线,在数据发送和接收的时候要进行拆卸和装配,串行-并行格式需要转换。

数据总线

数据总线(Data Bus),用来传输各功能部件之间的实际数据信息,它是双向传输的,它既可以把CPU的数据传送到存储器或I/O接口等其它部件,也可以将其它部件的数据传送到CPU。这里的数据的含义是广义的,它可以是真正的数据,也可以是指令代码、状态信息或者其他,大家不要被绕进去

通常总线被设计成传送定长的字节块,也就是(word)。字中的字节数(即字长)是一个基本的系统参数,各个系统中都不尽相同。另外计算机最小的存储单位字节(Byte),1 字节等于 8 位(1Byte=8bit),而位/比特(bit)是计算机最小的数据传输单位1 字节等于 8 位(1Byte=8bit)这个换算规则大家需要牢记

现在的大多数机器字长(计算机能直接处理的二进制数据的位数)要么是4个字节(4*8 =32位),要么是8个字节(64位)。本文我们不对字长做任何固定的假设

数据总线的位宽,也就是数据总线的宽度是计算机的一个重要指标,一般情况下:数据总线的位宽 = CPU的位宽 = CPU内部通用寄存器的位宽 = 机器字长,但是数据总线宽度不一定等于机器字长,比如下图中8088型号处理器,2者就不相等

数据总线的位宽为8位的话,数据总线数量有8条,由于每条传输线一次只能传输1位二进制数据,所以8根数据线一次可传送一个8位二进制数据(即一个字节)

地址总线

地址总线(Address Bus),地址总线专门用于传输的是地址信号,指出数据总线上的数据源地址、目的数据在主存单元或I/O 设备 的地址,也就是指向 CPU 将要操作的内存地址。地址总线是单向传输的(地址只能从CPU传向外部存储器或I/O设备的端口),其位数与主存空间的大小有关

CPU的寻址能力

计算机最小的存储单位字节(Byte),计算机将8个bit归为一组,为字节,每一个字节都对应一个内存地址。内存的地址是从0 开始编号的,然后自增排列,最后一个地址为内存总字节数 -1。CPU只需要知道某个数据类型的地址, 就可以直接去到对应的内存位置去提取数据了。

CPU的寻址能力与它的地址总线位宽有关,与数据总线宽度(CPU位宽=数据总线位宽)无关16位CPU的地址总线位宽可以是20位,也可以是24位。CPU的位宽最好不要小于地址总线位宽,需要通过北桥进行数据转换,工作起来比较复杂, 16位 CPU 一次最多只能操作16位宽的地址总线,最好16位CPU和16位的地址总线位宽搭配,但CPU的位宽不能大于地址总线位宽

地址总线位宽决定了CPU能直接访问的主存容量大小,CPU 通过地址总线来指定存储单元的位置(注意是字节而不是字),地址总线上能传送多少信息,CPU 就可以对多少个存储单元进行寻址。

如果一台8位计算机,其地址总线为16位的话,有16根地址线来传递地址信号,每一条线能够传递的数据都是 0 或 1
则其最大可寻址空间为2^16B= 64*1024B= 64KB,影响CPU的寻址能力是它的地址总线位宽,与其CPU位宽无关。

32位CPU最大支持4G内存?

64位、32位指的是CPU寄存器的数据宽度,也叫 CPU 的位宽,他们最主要区别在于CPU一次能计算多少字节数据

  • 32位CPU,表明处理器 一次可以计算 4 个字节(Byte),即一次可以计算32位(bit)数据。
  • 64位CPU,表明处理器 一次可以计算 8 个字节(Byte),即一次可以计算64位(bit)数据。

32位CPU最大支持4G内存,这是怎么算出来的?它的前提条件是CPU的位宽等于地址总线位宽
32位CPU,其地址总线位宽也是32位,根据地址总线位宽我们可以算出:2^32B = 4GB,2^35b = 4GB其最大内存寻址能力只能达到是4G。我们就算给这台32位的电脑装8G的内存条,也无法提高其计算能力。
但是我们刚刚只是举得最普遍的情况,32位CPU,其地址总线位宽也可以是36位,40位

控制总线

控制总线(Control Bus),用来传输的是控制或状态信号,控制总线是双向传输的,一般用于发送和接收信号,比如存储器读、存储器写、中断、设备复位等信号。控制总线的宽度决定了CPU对外部器件的控制能力

总线的共享性和独自性

总线具有分时和共享性:
分时是指同一时刻只允许有一个部件向总线发送信息,若系统中有多个部件,则它们只能分时地向总线发送信息。
共享是指总线上可以挂接多个部件,各个部件之间互相交换地信息都可通过这组线路分时共享。

也就是在某一时刻只允许有一个部件,占有总线的控制权,可以向总线发送信息,但多个部件可同时从总线上接收相同的信息

系统总线的结构

我们一直说系统总线的设计概念,我们来看下实际上计算机中的总线结构

单总线结构

最初的单总线结构只有一条总线叫做系统总线,把各个部分连接起来,所有设备间的通信都要经过系统总线,单总线结构就会显得负载比较重,同时只能有两个设备进行通信,其他设备间想要通信就必须等待。所以负载大,无法支持并发操作

双总线结构

由于I/O 设备的访问速度是非常慢的,CPU这么昂贵的资源,不能让它一直等待I/O 设备的响应,所以增加一条I/O 总线,用于在多个外部设备与通道之间传送数据,将低速 I/O 设备从单总线上分离出来。另一条是主存总线,用于在 CPU、主存和通道之间传送数据。

通道是具有特殊功能的处理器,能对I/O设备进行统一管理。

三总线结构

三总线结构在二总线结构上(主存总线, I/O 总线),新增DMA总线

DMA(直接内存访问)是现代计算机一个非常重要的特点,在它出现之前,主存总线和IO总线读取内存和IO设备的数据,都是有CPU所控制的,由于CPU的读取速度比主存、IO设备、硬盘上的读取速度差距快的多(完全不是一个量级的),CPU是非常昂贵的资源,不能让它一直等待主存、IO设备的响应数据,所以有了DMA之后,CPU将总线的控制权交给DMA,让DMA可以不受CPU的控制,由DMA控制器来实现和完成的,去独自与主存、IO设备交互。也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高

我们知道总线的控制权具有分时独占性,DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,DMA完成任务后通过归还总线控制权,由于DMA控制器和CPU都有访内请求,可将地址、数据等信号送到总线上,甚至都不需要经过"申请-建立-归还总线控制权"的过程,直接控制权转移,让DMA与CPU交替访问内存。由于耗时极短,产生"同时访问"内存的现象

所以DMA总线提高了 I/O 设备的性能,使其更快地响应命令,提高系统吞吐量。

还有四总线结构,PCI总线结构, 双独立总线结构等就不介绍了,感兴趣的自行去查阅相关资料。

总线传输的四个阶段

  1. 申请分配阶段:由需要使用总线的主模块(或主设备)提出申请,经总线仲裁机构决定将下一传输周期的总线使用权授予某一申请者。也可将此阶段细分为传输请求和总线仲裁两个阶段。
  2. 寻址阶段:获得使用权的主模块通过总线发出本次要访问的从模块的地址及有关命令,启动参与本次传输的从模块。
  3. 传输阶段:主模块和从模块进行数据交换,可单向或双向进行数据传送。
  4. 结束阶段:主模块的有关信息均从系统总线上撤除,让出总线使用权。

总线仲裁

由于计算机有多个设备,必然会存在多个设备同时竞争总线控制权的问题,这时候就需要总线仲裁,让某个设备优先获得总线控制权,获得了总线控制权的设备,才能开始传送数据。未获胜的设备只能等待获胜的设备处理完成后才能执行。

总线仲裁方式按其仲裁控制机构可分为集中总裁方式分布仲裁方式两种。

集中总裁方式

总线控制逻辑基本上集中于一个设备(如 CPU)中。将所有的总线请求集中起来,利用一个特定的裁决算法进行裁决,称为集中仲裁方式。集中仲裁方式有链式查询、计数器定时查询方式和独立请求方式

  1. 链式查询方式

总线上所有的部件共用一根总线,当有部件请求使用总线时,需经此线发总线请求信号到总线控制器。由总线控制器检查总线是否忙,若总线不忙,则立即发总线响应信号,经总线响应线 BG 串行地从一个部件传送到下一个部件,依次查询。若响应信号到达的部件无总线请求,则该信号立即传送到下一个部件;若响应信号到达的部件有总线请求,则信号被截住,不再传下去。也就是说“总线忙”信号的建立者是获得总线控制权的设备

在链式查询中,部件离总线控制器越近,其优先级越高;部件离总线控制器越远,其优先级越低优点:链式查询只需很少几根控制线就能按一定优先次序实现总线控制,结构简单,扩充容易。

缺点:对硬件电路的故障敏感,且优先级不能改变。当优先级高的部件频繁请求使用总线时,会使优先级较低的部件长期不能使用总线。

  1. 计时器定时查询方式

它采用一个计数器控制总线使用权,相对链式查询方式多了一组地址线,少了一根总线响应线 BG。它仍共用一根总线请求线,当总线控制器收到总线请求信号并判断总线空闲时,计数器开始计数,计数值通过设备地址线发向各个部件。当地址线上的计数值与请求使用总线设备的地址一致时,该设备获得总线控制权,同时终止计数器的计数及查询。

优点:计数可从“0”开始,此时一旦设备的优先级次序被固定,设备的优先级就按 0,1,...,n 的顺序降序排列,而且固定不变;计数也可从上一次的终点开始,即采用一种循环方法,此时设备使用总线的优先级相等;计数器的初值还可以由程序设置,故优先级可以改变,且这种电路的故障没有链式查询方式敏感。

缺点:增加了控制线数(若设备有 n 个,则大致需要 ⌈log2n⌉ + 2 条控制线),控制也相对比链式查询要复杂。

  1. 独立请求方式

每个设备均有一对总线请求线 BR_i_ 和总线允许线 BG_i_。当总线上的部件需要使用总线时,经各自的总线请求线发送总线请求信号,在总线控制器中排队,当总线控制器按一定的优先次序决定批准某个部件的请求时,给该部件发送总线响应信号,该部件接到此信号就获得了总线使用权,开始传送数据。

优点:响应速度快,总线允许信号 BG 直接从控制器发送到有关设备,而不必在设备间传递或查询,而且对优先次序的控制相当灵活。缺点:控制线数量多(设备有 n 个,需要 2n + 1 条控制线,其中加的那条控制线为 BS 线,作用是让设备向总线控制器部件反馈已使用完总线),总线控制逻辑更复杂。

分布仲裁方式

分布式仲裁方式不需要中央仲裁器,每个潜在的主模块都有自己的仲裁号和仲裁器。当它们有总线请求时,就会把它们各自唯一的仲裁号发送到共享的仲裁总线上,每个仲裁器将从仲裁总线上得到的仲裁号与自己的仲裁号进行比较,若仲裁总线上的仲裁号优先级高,则它的总线请求不予响应,并撤销它的仲裁号。最后,获胜者的仲裁号保留在仲裁总线上。

总线的性能指标

  1. 总线的传输周期。指一次总线操作所需的时间(包括申请阶段、寻址阶段、传输阶段和结束阶段),简称总线周期。总线传输周期通常由若干总线时钟周期构成。
  2. 总线时钟周期。即机器的时钟周期。计算机有一个统一的时钟,以控制整个计算机的各个部件,总线也要受此时钟的控制。
  3. 总线的工作频率。总线上各种操作的频率,为总线周期的倒数。实际上指 1 秒内传送几次数据。
  4. 总线宽度。又称总线位宽,它是总线上同时能够传输的数据位数,通常指数据总线的根数,如 32 根称为 32 位总线。
  5. 总线带宽。可理解为总线的数据传输率,即单位时间内总线上同时能够传输的数据位数,通常用每秒传送的字节数来衡量,单位可用 B/s 表示。总线带宽 = 总线工作频率 * (总线宽度 / 8)。
  6. 总线复用。总线复用是指一种信号线在不同的时间传输不同的信息,因此可以使用较少的线传输更多的信息,从而节省空间和成本。
  7. 信号线数。地址总线、数据总线和控制总线 3 种总线书的总和称为信号线数。

其中,总线最主要的性能指标为总线宽度、总线工作频率、总线带宽,总线带宽是指总线本身所能达到的最高传输速率,它是衡量总线性能的重要指标。总线带宽 = 总线宽度 * 总线频率。例如总线工作频率为 22 MHz,总线宽度为 16 位,则总线带宽= 22 * (16 / 8)= 44 MB/s

尾语

感谢大家读到最后,想信大家都了解了总线是什么?计算机为什么使用总线?以及总线的设计理念,总线一些通用的特性,总线和内存的交互,接着又聊到了总线的结构,DMA等现代计算机的重要技术,最后又介绍总线仲裁和其性能指标,希望大家有所收获


参考资料:
《深入理解计算机系统 第三版》
《计算机组成原理》
《深入浅出计算机组成原理》
https://blog.csdn.net/qq_42896653/article/details/105329078
https://blog.csdn.net/weixin_42394252/article/details/106073221
https://blog.csdn.net/qq_42896653/article/details/105329078


本篇文章到这里就结束啦,如果我的文章对你有所帮助,还请帮忙一键三连:点赞、关注、收藏,你的支持会激励我输出更高质量的文章,感谢!

计算机内功、JAVA源码、职业成长、项目实战、面试相关等更多高质量文章,首发于公众号「小牛呼噜噜」,我们下期再见。

有关什么是计算机中的高速公路-总线?的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  3. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  4. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  7. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  8. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

随机推荐