原文:CPU阿甘

 前言
上帝为你关闭了一扇门,就一定会为你打开一扇窗这句话来形容我最合适不过了。
我是CPU, 他们都叫我阿甘, 因为我和《阿甘正传》里的阿甘一样,  有点傻里傻气的。
上帝把我制造出来, 给我了一个很小的脑容量, 为数不多的寄存器能临时的记一点东西, 但是上帝给我打开了一扇特别的窗户, 那就是像阿甘一样,跑的飞快。
到底有多快呢?  我这么比喻一下吧,  我的工作都是以纳秒为单位的, 你们人间的一秒, 我可能已经做了1000,000,000 (10亿)次动作了。
相比而言, 内存比我慢100倍, 硬盘比我慢1000多万倍, 你说我快不快?
 启动
我住在一个机箱里,每天早上一阵电流把我叫醒, 还夹杂着嗡嗡的声音, 我知道我忠实的护卫电风扇又开始工作了, 我特别怕热, 又运行的飞快, 如果没有电风扇给我降温, 我很快就会生病, 生病的后果很严重, 那就是我的伙伴们像内存了,硬盘了。。全部都要罢工了, 没有我这个系统就会陷入的一片死寂。
我听说有些CPU的福利很好,竟然待在恒温恒湿,一尘不染的托管机房里,让我好生羡慕。
我的脑容量很小, 所以醒来后只想起了我的创造者告诉我的几件事情 :1. 你的工作就是运行指令2. 你不能保存指令, 你的指令全在内存里3. 你的第一条指令在内存的最顶端处0xFFFFFFF0
那还有什么可说的, 赶紧打电话给内存要指令,电话通过系统总线, 还得通过I/O桥电话局需要转接一下, 再通过存储总线接通 内存。 
"哥们, 把这个地址处的指令给我说一下吧"
"你是谁?" 内存竟然把我忘了, 当然,他断了电和我一样,失忆了。
"我是阿甘啊, 我们经常聊天来着, 你忘了?"
内存磨磨唧唧半天才把数据发了过来(比我慢100倍啊), 这是一条跳转指令,  我立刻回忆起来了, 这是我的老朋友BIOS 等着我去运行他那一堆指令呢。
我给BIOS打电话:  “老弟,今天干点啥?”
“阿甘,早上好 "   BIOS从不失忆,把所有人都记得清清楚楚   “ 还不是老一套啊,无非做一下系统的自检, 看看内存,硬盘,显卡等这些老伙计们有没有问题, 有问题的话用小喇叭提示一下主人 ”
这些过程我已经轻车熟路了, 很快搞定, 像往常一样,没有问题, 我还把一个叫做中断向量表的东西给弄好了, 我知道一会而要用
这些东西都搞完了,BIOS果然告诉: "阿甘, int 0x19"
我赶紧去刚弄好的中断向量表中去查第19号, 顺藤摸瓜又找到对应0x19的一大堆指令。
执行吧,  这堆指令把将磁盘的第一扇区(磁盘最开始的512字节)运到内存的0X0000:0X7C00处,然后我就从此处接着执行。
我想起来了, 接下来有一大堆精巧的指令把迷迷糊糊的操作系统从硬盘中唤醒, 运输到内存中来。(此处实在是复杂, 略去10万字。。。。)
你看这就是为啥他们叫我阿甘, 我做事飞快,但非得别人告诉去哪里执行才行, 要不然我就只会坐在那里无所适从。
 运行
操作系统一旦进入内存,立刻就是老大, 所有人都得听他指挥。
我也发现我的周围出现了一个屋子:进程屋屋里堆着一大堆东西, 什么进程描述信息包裹了, 进程控制信息包裹了, 我都不太关心, 我只关心最最重要的两件东西:1.  我工作必备的寄存器, 就放在我面前的工作台上。2.  程序计数器, 我用它记住我要执行的下一条指令地址。
"阿甘, 别来无恙啊" , 操作系统对我还是挺不错的, 先给我打招呼。
"Linux老大, 今天有什么活啊", 我每次都表现的积极主动。
"来,把这个hello world 程序给运行了"
Hello world 程序还在硬盘上睡着呢,  得先把他也装载到内存里, 要不然我怎么执行啊。
于是我就拿起电话打给硬盘, 电话通过系统总线来到IO桥电话局, 再转接到IO总线,这才来到硬盘这里。 
我在电话里请他把数据给我运过来, 然后我就无所事事的坐在那里等。
Linux 老大立刻就怒了 : 阿甘, 告诉你多少次了, 你小子怎么还在等硬盘给你发数据!
是的, 我忘了一件事,硬盘比我慢太多了, 我执行一条指令大概是1ns  ,在用来读磁盘的16ms里, 我能潜在的执行1600多万条指令啊。
我感到深深的愧疚, 赶紧拿起电话打给硬盘 : 哥们, 按我们之前商量好的,用直接内存访问(DMA)啊, 你直接把数据装载到内存吧, 不用经过我了,  装载完成以后给我发个信号。
"这还差不多"  Linux 老大心情好了些 “阿甘,数据还没来, 别闲着, 这有一个菲波那切数列数列, 来算一下吧”
"肥波纳妾数列?  这名字好古怪,老大, 其实你也知道, 我脑子小,懒得去理解那是啥意思, 你把进程屋切换下,把程序计数器设置好,指向下一条指令, 我一条条指令执行就得了“  我挺没追求的。
"真是个阿甘啊! ”老大感慨到。
我所处的进程屋立刻发生了变化(当然,这也是我辅助Linux老大干的), 各种包裹的信息都变了,  尤其是寄存器和程序计数器。
于是我就开始计算这个什么纳妾数列 ,但是这个数列似乎无穷无尽, 哪个无脑子的程序员写了个无限循环吧。
正在这时, 我便收到了一个电话, 说是Helloworld的数据已经装载到内存了,  让我去处理。
我放下手中的活, 保存好现场, 就去处理那个Helloworld,  果然数据已经都好了, 那就切换过去运行吧。
其实老大并不知道, 任何人,只要你运行了相当多的数量的指令以后, 你都能悟到这些程序的秘密。 我CPU阿甘虽然傻傻的, 但也架不住执行这数以万万亿的指令给我的熏陶啊。
这个秘密就是:程序都是由顺序,分支,循环来组成的。  其实分支和循环在我看来都是跳转而已。
所以我的工作就是打电话问内存要一条指令, 执行这个指令, 如果是个跳转指令的话,我就问内存要跳转的目标地址的那一条指令, 继续执行, 生活就是这么简单。
奥对了, 当然也有复杂的, 就是函数调用, 我得和内存紧密配合才能完成。  这个咱下回再说。
 新装备:缓存
提到内存, 这真是我的好哥们, 没有他,我几乎什么事儿都干不成, 更重要的是他比硬盘快的多, 读取一次数据, 只需要 100 纳秒左右。 这样我们俩说起话来就轻松多了。
每次他都说: "阿甘, 幸亏有你给我聊天, 要不然我肯定被活活的闷死不可, 那个硬盘说话是在太慢了"
"它为啥那么慢?"  我每次都问
"硬盘是个机械是的玩意, 一个磁头在一碟高速旋转的磁片上挪来挪去,光定位就慢死了"
"那主人为什么要用硬盘?"
"人家虽然慢, 但是不怕停电, 哪像你和我,一停电全部都失去记忆了。"
确实是, 人不能把好事都占全了啊。
我的指令中有些完全用我的寄存器就能完成, 但是有很多都需要读写内存的数据, 再加上所有的指令都在内存中存着,  虽然它只比我慢个100倍, 但指令多了我还是有点受不了。
我给内存说:"哥们, 你能不能再快点!"
内存说: 拜托, 这已经是我的极限了, 阿甘, 你自己再想想办法吧 ! 我给你说啊, 我留意了你最近访问的指令和数据, 我发现了个规律“
"啥规律?"
"比如说吧, 你访问了我一个内存位置以后过不多久还会多次访问, 还有,一个内存位置被访问了, 附近的位置很快也会访问到"(码农翻身注: 这其实叫程序的局部性原理
我还以为是啥规律, 其实我早就注意到了。
"这有啥用啊?”
"既然你经常访问同一块区域的东西, 你想想如果把这些东西缓存在你那里会怎么样.... "
我一想有道理啊!  加个缓存试试!
从此以后,我每次读写指令和数据, 都问缓存要, 缓存没有才给内存打电话。
果然, 由于局部性原理的存在, 我发现的确是快了不少啊。
当然也有缺点, 那就是Linux老大在做程序切换的时候, 缓存就会失效,因为两个程序之间没什么联系,局部性原理不起作用,  所以需要重建缓存。
 自我提升:流水线
缓存让我的工作更有效率, 得到了Linux老大的表扬:"阿甘, 我看你很聪明嘛, 都会用缓存了"
"我哪有那么聪明,都是内存的点子。老大,不过我学会了一个重要的东西 :当你改变不了别人的话,抱怨也没用, 还是先改变一下自己吧"
"挺有哲理的吗, 希望你明天重启后还能想起来" Linux老大笑话我。
"我最近又发现了一个问题, 正苦恼着呢, 你看我有四只手, 第一只手负责打电话问内存要指令, 第二只手翻译指令, 第三只手真正执行, 第四只手有时候还得把结果写回内存。  问题是, 我发现经常只有一只手在忙活, 其他都在闲着, 你看第一只手取指令, 其他手只能等着。  第二只手翻译指令的时候,其他三只也得等“
"看来以后我们不能叫你阿甘了, 你已经开始思考了" Linux老大笑了 
“这问题好解决, 给你举个例子,你听说过洗车没有?  和你差不多, 也是先喷水, 再打洗洁剂, 再擦洗, 最后烘干,  但人家的工作方式和你不一样,人家是流水线作业, 你想想, 一辆车在烘干的时候, 后边是不是还有三辆车,分别在喷水, 打清洁剂 和擦洗 , 每个步骤都不会空闲。 ”
"这么简单的道理我怎么都没有想到呢? 我也可以搞个流水线啊, 这样每只手都利用起来了"
别人都说我们高科技, 但其实原理都蕴含在生活之中啊。 
有了缓存和流水线的帮助, 让我的工作大大的加快了,大家都对我刮目相看。 他们想给我起个新名字:超人 , 不过我还是更喜欢 他们叫我“阿甘”, 多亲切。
 尾声
我一丝不苟,兢兢业业的运行指令, 时不时和伙伴们聊天, 很快一天就过去了, 又到了晚上,我知道关机的时刻到了, 赶紧挨个给他们道别。 
很快那些让我兴奋的电流消失了,风扇的嗡嗡声也没有了, 我再也无法打出电话,整个世界沉寂了。
明天将会是新的一天。
备注: 本文内容主要来自于《深入理解计算机系统》, 这本书非常棒,值得每个程序员仔细研读。公众号:码农翻身“码农翻身”公众号由工作15年的前IBM架构师创建,分享好玩,有趣的编程知识。

【转载】CPU阿甘的更多相关文章

  1. CPU阿甘之烦恼

    转自“码农翻身”公共号,原文地址CPU阿甘之烦恼 总结:(程序加载到内存运行的演变过程) 内存存放程序.OS负责加载程序到内存.CPU负责运行内存中的程序 1.串行:加载一个完整程序到内存,CPU运行 ...

  2. CPU阿甘:函数调用的秘密

    个人感言:真正的知识是深入浅出的,码农翻身" 公共号将苦涩难懂的计算机知识,用形象有趣的生活中实例呈现给我们,让我们更好地理解.感谢"码农翻身" 公共号,感谢你们的成果, ...

  3. CPU阿甘

    本系列文章全部摘选自"码农翻身"公众号,仅供个人学习和分享之用.文章会给出原文的链接地址,希望不会涉及到版权问题. 个人感言:真正的知识是深入浅出的,码农翻身" 公共号将 ...

  4. (转载)CPU、内存、硬盘、指令以及他们之间的关系

    CPU.内存.硬盘.指令以及他们之间的关系 最近读完<程序是怎样跑起来的>以及<深入理解计算机系统>的3.6.9章节后对计算机的组成有了更深入细致的了解,现总结一下对CPU.内 ...

  5. 转载->CPU的内部架构和工作原理

    CPU的内部架构和工作原理 本片博客转自:http://www.cnblogs.com/onepixel/p/8724526.html  感谢博主分享! 内部架构 CPU 的根本任务就是执行指令,对计 ...

  6. Javascript:一个屌丝的逆袭

    HTML负责结构, CSS负责展示, 而我(加上AJAX, JSON) 负责逻辑.于是前端编程三剑客形成了. http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExN ...

  7. 网络编程基础【day10】:我是一个进程(三)

    本节内容 1.引子 2.进程的诞生 3.线程 4.争吵 一.引子 我听说我的祖先们生活在专用计算机里, 一生只帮助人类做一件事情,比说微积分运算 了.人口统计了 .生成密码.甚至通过织布机印花 !   ...

  8. Casual Note of OS

    20170104 冯诺依曼计算机(遵循冯诺依曼结构设计的计算机:存储器.运算器.控制器.输入设备.输出设备)之前也有计算机,不过在那之前的计算机是专用的,不可编程,只能干特定的事情没法干其他事.与之前 ...

  9. 【java基础 7】java内存区域分析及常见异常

    本篇博客,主要是读书笔记总结,还有就是结合培训分享的总结,没有太多的技术含量! java 的自动内存管理机制,使得程序员不用为每一个new惭怍的对象写配对的delete/ free代码(回想起C++的 ...

随机推荐

  1. Kali-linux Arpspoof工具

    Arpspoof是一个非常好的ARP欺骗的源代码程序.它的运行不会影响整个网络的通信,该工具通过替换传输中的数据从而达到对目标的欺骗.本节将介绍Arpspoof工具的 使用. 9.8.1 URL流量操 ...

  2. 前端页面 SEO 优化

    SEO要点:1.语义化html标签,用合适的标签嵌套合适的内容,不可过分依赖div,对浏览器更友善就能更容易被抓取.2.重要的内容html代码放在前面/左边.搜索引擎爬虫是从左往右,从上到下进行抓取的 ...

  3. Vscode 格式化vue Template代码段

    1.安装 vetur 2.在User Setting中增加设置: "vetur.format.defaultFormatter.html": "js-beautify-h ...

  4. IIS中ASP.NET虚拟目录不继承主站点web.config设置的办法(转载)

    ASP.NET提供了强大的Web.config来配置网站,一般来说一个网站只有一个根目录下的Web.config文件,有时候我们希望子目录有着不同的权限或者参数设置,则可以在相应子目录增加一个Web. ...

  5. Set集合之HashSet类

    HashSet简介 HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类.HashSet按Hash算法来存储集合中的元素,因此具有良好的存取和查找性能. HashSet特 ...

  6. Python的迭代器与装饰器

    '''迭代器:两个基本方法:iter()和next()迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合等第一个元素开始访问,直到所有的元素被访问结束,迭代器只能往前不会后退. 迭代器有两个基本 ...

  7. 20181101noip模拟赛T1

    思路: 我们看到这道题,可以一眼想到一维差分 但这样的复杂度是O(nq)的,显然会T 那么怎么优化呢? 我们会发现,差分的时候,在r~r+l-1的范围内 差分增加的值横坐标相同,纵坐标递增 减小的值横 ...

  8. 关于JQuery的异步注册

    在采用JQuery进行表单异步提交时,前台传入的是json数据格式,后台controller用map接收,再传回前台进行结果判断时,if-else接收结果()里面,尽量不要出现“=”,不然判断语句失效 ...

  9. [已解决] 设置无效字段为-1 时,引发的 DataGridView DataError

    由于问题一句话说不清.所以标题里也没写明白.大概情况是这样.我一直使用dotNetBar控件来做UI,其中的DataGridView很常用.过去一直有发现DataError的错误,通过截取消息暂时屏蔽 ...

  10. tp5上传压缩包到相应文件并自动解压到相应文件下

    <?phpnamespace app\admin\controller\upload; use app\common\controller\Backend;use think\db;use th ...