草庐IT

聊聊开关和CPU之间故事

xiaoniuhululu 2024-02-11 原文

目录

作者:小牛呼噜噜 | https://xiaoniuhululu.github.io

大家好,我是呼噜噜,在先前的一篇文章计算机中数值和字符串怎么用二进制表示?中,我们知道了计算机为什么会采用 0 和 1 组成的二进制,来表示所有的信息,比如机器指令、数字、字符串、声音、图片、视频等等。

我们本篇文章来看看计算机在硬件层面究竟是怎么表示二进制的,CPU究竟是怎么实现的?通过本文的学习,我们也可以反过来明白为什么计算机会采用二进制了。

开关

我们在生活中,处处都是开关,比如控制灯的开关

我们可以发现一个很简单的现象:

  1. 串联的开关,只有2个开关都闭合,灯泡才亮。这也就是布尔代数中"逻辑运算与"
  2. 并联的开关,只要有1个开关闭合,灯泡就会亮。这也就是布尔代数中"逻辑运算或"

我们以最简单的2个数,0和1来举个例子,写出其布尔代数的真值表:

电报和继电器

在人类信息传递发展的历史上,长途信息传递一直是非常困难的时,当时常见的方式有,比如人骑马送信,训练信鸽、点燃烽火,但信息传递的效率都非常低效。直到电报的出现,电报思想的正式成形是在19世纪早期,它的让人类传递信息的效率得到极大的提升。

电报利用电的特性来传递信息,早期设计复杂且不稳定,传递的信息复杂度又比较低,1837年美国人摩尔斯通过电磁感应改良了发报机,并发明了摩尔斯电码。他将电报划分为2种信号,短促的"点信号"和长一点的"划信号", 将把“点”当成“1”,把“划”当成“0”(这不就是二进制嘛),并编写了个“字典”将字母及数字编码一一对应,这样就能传递复杂的信息,在未来产生了巨大影响力,意味着现代通信的开始。

由于早期的电报传输,需要铺设电线,但是随着电线越长,其电阻就越大,电信号常常传输过程中被消耗点,这样接受方就无法接收到信息了。幸运的是,工程师发明了继电器,其原理就是接收微弱的信号,然后不断地通过新的电源重新放大已经开始衰减的原有信号,最后把它增强后发送出去

当开关是打开的话,灯泡是不亮的;但当开关是闭合的话, 电流流过围绕在铁棒上的线圈,会发生电磁效应,铁棒就具有了磁性,会将弹簧片吸下来,右边电路就通了,灯泡就会亮了。这样通过继电器,一段段放大信号,电报就能长距离传输信息了。

虽然继电器有放大信号的作用,但和开关一样继电器也可以串联或并联以执行逻辑中的简单任务,继电器比起普通的开关的优势在于继电器无需直接被输入者控制,可以被其他继电器控制,这样就可以组合完成更复杂的操作。比如我们可以通过继电器实现: 当我们闭合开关时,灯泡关闭;当我们打开开关时,灯泡去点亮这种灯泡的状态和开关的闭合状态相反的操作,普通开关是无法实现这种操作的。这些电路物理的表象下隐藏的逻辑关系,一直没有被人发现。

直到1938年,克劳德·香农在麻省理工学院所写的硕士论文《A Symbolic Analysis of Relay and Switching Circuits》中阐述了继电器和开关电路中的符号分析之间的关系,他将开关、继电器、二进制、布尔代数联系起来。也就是发现人类可以通过开关和继电器这些普通的电路,直接就能实现布尔代数各种逻辑运算操作。这些继电器的组合被称为逻辑门,他们构造基本的逻辑电路,也叫门电路

门电路

上面是3种最最基本的门:

  1. 与门,两个开关只有同时打开,电流才会通过,灯泡才会亮
  2. 非门,当开关闭合时,电流会通过,灯泡会亮;开关打开,电流不能通过反而,灯泡熄灭
  3. 或门,两个开关中只要有一个打开电流就能通过,灯就会点亮

这些门其实就是一个个"开关"的抽象, 以后我们需要的各种复杂的逻辑都可以通过这3个门来实现,真的是非常奇妙
我们再来看一个常见的门:异或门XOR

我们先写出其真值表(真值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效):

A B X(输出)
0 0 0
0 1 1
1 1 0
1 0 1

其表达式也就是:

通过表达式我们就能知道,把非A与B的值 和非B与A的值 通过或门加起来就能得到异或门

材料学的发展

上世纪材料学的发展也大力推动了计算机的蓬勃发展,计算机的硬件出现了3次大的更新换代

继电器与哈佛Mark1号

在1944年,为了给美国曼哈顿计划跑模拟,IBM建造出来首台自动按序控制计算机哈弗Mark1号,有76万五千个组件,300万个连接点和500英里长的导线,重达4500公斤,占地面积有房间那么大。其大脑是由继电器组成的,其一秒能做3次加或减,乘法花费6秒,除法花费15秒

由于继电器的金属臂有“质量”,无法快速开关,1940年一个好的继电器一秒钟可以翻转50次,但是任何会动的机械都会随着时间出现物理磨损,部件会损坏,随着继电器数量增加,故障概率也会增加。真的是又慢又容易坏的大家伙,但瑕不掩瑜,其依旧具有跨时代的意义。

真空管与巨人一号

在1904年,英国物流学家弗莱明就已经开发了一种新的电子组件,叫做真空管,也就是把两个电极装在一个气密的玻璃灯泡里,但弗莱明的这个电子部件,电流只能单向流动,俗称称为 "二极管"。要想制作计算机,需要能够控制电子的流动的东西。

在 1906 年,美国发明家"李·德富雷斯特"在"弗莱明"设计的两个电极之间,加入了第三个"控制"电极(一 种栅栏式的金属网,形成电子管的第三个极),向"控制"电极施加正电荷,它会允许电子流动;但如果施加负电荷,它会阻止电子流动。被命名为真空三极管,这样就能形成一个"开关",可以“断开或闭合电路”。

由于真空管内没有会动的组件,想较于机械装置,磨损更少,又没有金属臂的限制,每秒可以开闭数千次,继电器一秒钟只能翻转50次左右,效率大大的提升。

第一个大规模使用真空管的计算机是"巨人1号",标志着计算机从机电转向电子,电子计算机的大门自此打开。由工程师Tommy Flowers设计,完工于1943年12月,用于二战时破解德国军事通讯密码。

晶体管与IBM608

虽然真空管做计算机的大脑,解决了继电器许多缺陷,但是其还是容易损坏,就像灯泡一样烧坏。到1950年代,真空管计算机都达到了极限。

1947年,贝尔实验室发明了晶体管,其成为了新的"开关",也标志着一个全新的计算机时代到来。晶体管不仅体积小,响应速度快(每秒切换开关能达到上百万次),而且使用寿命也非常悠远,准确 性高,稳定性好,不易损坏。关键它可以做得非常小,一块集成电路即可容纳十几亿到几十亿 个晶体管。

晶体管泛指一切以半导体材料为基础的单一元件,半导体顾名思义,可导电也可不导电,是常温下导电性能介于导体与绝缘体之间的材料,一般有硅、锗、砷化镓等

IBM608第一个完全用晶体管,消费者也可以买的起计算机。该计算机有3000个晶体管,每秒执行4500次加法,80次左右的乘除法。

计算机2大特性:计算能力和记忆能力

通过本文的阅读,我们知道了开关是一个生活中很普通的东西,但香农将开关、布尔代数联系的一起后,产生了化学反应。可以用一个个开关组合起来,成为门电路,从而能够造成CPU。

随着材料学等发展,开关也从继电器到真空管,再到晶体管,相应速度,提交,使用寿命,成本都得到了明显的改善。他们制造出来的计算机也慢慢的变成了我们现在熟悉的计算机。

计算机的大脑就是CPU,我们知道CPU内最重要的2个部件是寄存器和计算单元那么如何用开关来让计算机拥有计算能力和记忆能力?大家可以思考一下,后面的文章让我们抛开硬件,通过抽象出来的逻辑门来一步步设计和实现一个CPU。


参考资料:
《深入理解计算机系统》
《编码:隐匿在计算机软硬件背后的语言》
《深入浅出计算机组成原理》
《数字电子技术基础》
《穿越计算机的迷雾》
百度百科


全文完,感谢您的阅读,如果我的文章对你有所帮助的话,还请点个免费的,你的支持会激励我输出更高质量的文章,感谢!

原文镜像:聊聊开关和CPU之间故事

计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章,首发于公众号「小牛呼噜噜」,我们下期再见!

有关聊聊开关和CPU之间故事的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  3. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  4. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  5. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  6. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  7. ruby - 在模块/类之间共享全局记录器 - 2

    在许多ruby​​类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..

  8. ruby - 在两个 ActiveRecord 类之间合并/复制属性的好方法? - 2

    之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote

  9. ruby-on-rails - 2个用户之间的产品订单 - 2

    我有三个模型:User、Product、Offer以及这些模型之间的关系问题。场景:用户1发布了一个产品用户2可以向用户1发送报价,例如10美元用户1可以接受或拒绝提议我现在的问题是:用户、产品和报价之间的正确关系是什么?我如何处理那些“接受或拒绝”操作?是否有更好的解决方案?用户模型:classUser:productsend产品型号:classProduct:usersend提供模型:classOffer提前致谢:)编辑:我正在使用Rails3.2.8 最佳答案 警告:小小说来了第1部分:设置关联我建议阅读Railsguideo

  10. Ruby:read_timeout 和 open_timeout 之间的区别 - 2

    标题本身就说明了......read_timeout和open_timeout之间有什么区别? 最佳答案 open_timeout是您愿意等待“打开连接”的时间。在TCP上下文中,在放弃尝试并引发超时错误之前等待握手完成的时间量。read_timeout您可能会猜到,是您愿意等待从连接方接收到某些数据的时间。一个例子可能会清楚地说明这一点:在SOAPoverHTTPoverTCP上下文中(简化):您尝试与服务器建立TCP连接。如果建立连接的时间比open_timeout长,则放弃连接尝试并引发/发出/返回超时错误。如果连接成功,您发

随机推荐