计算机的底层逻辑

关于底层的一些笔记: 常说要多了解点计算机底层的东西, 那么问题有: 1.要了解多少底层东西(才够用), 2.底层有多少东西要了解? 最近发现底层真是个无底洞: 平常常说CPU/计算机是工作在0/1的基础上的, 但这么说其实没有多少作用: 在用高级编程语言编程时看到的明明就是具体的字符字母, 平常使用电脑时看到的明明就是GUI图形界面, 哪里来的0/1之说?! 而你说CPU使用分页表去多级寻址, 却连一个分页表都看不到, 只能靠想象与抽象去理解, 难怪计算机这么难学(假如果真如此的话): 在一台具象的电脑之下, 隐藏里太多的细节故事, 我看称之为事故也不为过了.

M

思维模式: 不同编程层次中的几种思维模式:

  • 使用高级编程语言(如C++/Python), 脑力主要集中于编程语言的语法, 库的使用, 算法的实现, 程序的设计, 项目环境配置, 等等;

  • 使用底层(并非低级)编程语言(如汇编), 则思维模式需转向到各种寄存器, 各种基本操作之间的顺序, 等;

其实还不止以上所列的两种模式/习惯, 假如把编译器也算进去的话, 那么又多了一种思维模式/习惯(扫描, 编译, …), 还可以有:

  • 计算机硬件的总线: 数据总线, 地址总线和控制总线, 冯诺依曼架构(指令与数据共用内存)和哈佛架构(指令与数据各自有各自的内存);
  • CPU指令流水线: 取值, 解码, 执行, 存储, 写回, 5个阶段, 它们的处理时间最好相等, 要不然最慢的流水线级处理时间将成为系统的时钟周期, 以及流水线处理中的”冒险”(Hazard)概念(导致流水线耽搁不能按时按设计执行);
  • BIOS也是一种软件程序: 完全超越了高级编程语言的概念(更重要, 关乎开机及硬件正常), 比汇编还要更接近硬件(它无法用编译器编译出?!), 确保(开机时)同一个计算机中的芯片(chips), 硬盘(hard drives), 端口(ports)及CPU能一起正常运转;
  • 视窗X Window系统: 超越原先的BIOS单色调简单图形/形状, 转而将更多颜色, 更多形状的界面(GUI)绘制到屏幕上, 由此也引出CPU与GPU的关系: CPU发送某种命令给GPU, GPU负责”计算/生成”屏幕上的具体像素值;

此外, 还有此外, 如GPU中也有BIOS等等, 不一而足. 以上举了这么些不同范畴的概念, 只不过想说明下计算机的”高层/底层”的思维习惯/模式可以有多么得不同(这可能是导致”学不进去”的一个原因), 而在学习/了解的过程中要保持一种”失望/我不懂”的预期, 才能在费脑细胞的计算机学习中”存活下去”.

以下列举一些常识性(HowWorks)的原理, 就这么些原理, 也都是和计算机体系相关的, 不过, 还是将它们当做边角料吧, 对它们有一定的常识性认识就好了:

操作系统原理[REF], 显卡原理[REF], 模拟数字信号转换[REF], 电视(显示器)原理[REF], 触屏原理[REF], Bits与Bytes工作机制[REF], 数字电路门工作原理[REF], 街机改造原理[REF], 微处理器原理[REF], 电脑的构造[REF], C语言基本机制[REF], 电脑需要一粒电池的原因[REF].

另: 查某些资料最好都要去google搜索, 百度搜索的同质化太严重, 而且中文环境的内容质量也是要考虑的要点, 如BIOS的介绍();

PC历史, https://computer.howstuffworks.com/history-of-the-personal-computer.htm

说了这么多,

Reference

1.CPU自制入门;

2.https://computer.howstuffworks.com/bios.htm;

显卡绘图原理: (显卡背景/历史原因) 显卡最初不是单独存在的, 而是作为主板上的某块部件集成于其上的, 但由于对于高质量图形显示的需求的驱动, 显卡的计算量和电路部件都增加了, 显卡就以一个独立于主板的部件存在于电脑中了. 总体来说, 可以把显卡理解成计算机中的另外一个处理器, 它听令于CPU, 专门根据CPU的指令/数据决定如何处理屏幕上的每一个像素.

从硬件上分析, 显卡上的主板连接(显卡插槽), 连接着计算机的总线(Bus), 而通过总线, CPU将绘图”命令/数据”发送至GPU, 而GPU上的内存(即显存), 负责接收这些”命令/数据”, 作为GPU计算的”取指/数据写回”来源, 而显卡上的IO负责把显示数据通过接口(如: VGA/DVI)发送给显示屏, 如下, 是显卡的工作任务描述:

“根据二进制数据生成图像是一个很费力的过程, 为了生成三维图像, 显卡首先要用直线创建一个线框, 然后, 它对图像进行光栅化处理(填充剩余的像素). 此外, 显卡还需添加明暗光线, 纹理和颜色, 对于快节奏的游戏, 电脑每秒钟必须执行此过程约60次. 如果没有显卡来执行必要的计算, 则电脑将无法承担如此大的工作负荷”

以上关于显卡原理的描述和分析的详细信息, 可以参考索引2的网页.

DirectX/OpenGL, 驱动程序 DirectX和OpenGL是在OS之下的API(应用程序编程接口), 它提供用于复杂任务(如: 三维渲染)的指令, 用于软硬件间的高效通信, 尤其是使用大量图形计算的游戏软件. 驱动程序, 则是OS与硬件间通信的程序, 可以理解成OS操作硬件的一个API(侧重Interface).

以鼠标为例, 理解它与屏幕, CPU之间的关系和工作机制;

Reference:

  1. Sohu, 显卡绘图原理, ref;
  2. Cnblogs, 计算机底层访问显卡, ref;

  3. PcOnline, 显卡工作原理浅析, ref;

关于X Window

一直以来, 都以为X Window是计算机OS中的一套图形化标准, 还以为它掌管着屏幕上的一切可视化(没错, 就是现在显示这篇文章的屏幕), 其实, 它只不过是一些显示系统中的一个, 在它之前, 已经有如下几个位图式软件显示系统的存在:

施乐公司提出的Alto(1973年)和Star(1981年), 阿波罗电脑公司提出的Display Manager(1981), 苹果计算机提出的Lisa(1983年)和麦金塔(1984年), 在UNIX世界也有雅典娜工程(1982年)和Rob Pike的Blit终端机(1984年).

故X Window并无特别之处, 它是和其它类似系统并列的一个显示系统, 但它工作在Unix/Linux之下, 它的组成可分为: 1.XServer, 2.XClient, 3.XProtocol. 而根据引用[6]的总结, X Window的运行过程如下:

1
2
3
4
5
(1) 用户通过鼠标键盘对XServer下达操作命令
(2) XServer利用Event传递用户操作信息给X client
(3) XClient进行程序运算
(4) XClient利用Request传回所要显示的结果
(5) XServer将结果显示在屏幕上

维基百科对XWindow管理器的运作原理描述如下[Ref]:

当视窗管理器开始运作时,X服务器和客户端之间的交互,会重定向到视窗管理器。每当要显示一个新视窗时,这个请求便会被重定向到视窗管理器,它会决定视窗的初始位置。此外,大部分较新的视窗管理器会改变视窗的亲属关系,通常会在视窗顶部加上标题栏,并在视窗周围加上装饰性的框架。这两个部分皆由视窗管理器来控制,而不是其它程序。因此,当用户点击或拖曳那些组件时,视窗管理器会进行适当的动作(如移动或改变视窗的大小).

上述引用段说了两件事情: 1.视窗和顶部标题栏及框架的关系, 2.绘制视窗的是XServer, 但改变其大小的是视窗管理器(即视窗管理器叫XServer重新绘制另一个size的视窗).

视窗管理器也负责处理图标,图标并不存在于X Window核心协议的层次中。当用户将视窗最小化时,视窗管理器会取消视窗的映射(使其不可见),并完成适当的动作,将视窗改显示成图标。某些视窗管理器并不支持图标功能。

根据上述描述, 推测: 在最小化图标时, 同样的操作是, 视窗管理器让XServer重新绘制视窗的大小为0(?!)使其不可见.

视窗管理器主要的目标,就如同其名,是用来管理视窗的。许多视窗管理器提供附加的功能,如处理鼠标在根视窗上的点击,呈现出窗格以及其它的可视化组件,处理按键(例如 Alt-F4 可关闭视窗),判定哪一个应用程序在引导时运行等等。

关于图形界面的几点总结(个人直觉性思考):

  • 无论是旧式终端单色调文本界面还是现在多重颜色的图形界面, 计算机中都得有处理输出显示结果到屏幕的部分, 旧式的界面简单, 不需要单独显卡, 现在的界面图形丰富计算量大, 故显卡应运而生;

  • 有了上一步的推断, 我们继续推: 在启动计算机时, CPU和GPU等硬件在BIOS的检查之后都一起启动了, 此时计算机就有了显示功能(屏幕就能用了), 此时我们的桌面还没看到, 但不代表OS对GPU的”驱动/使用”功能还没建立起来, 当然, 相比桌面丰富多彩的颜色(往往是我们的壁纸), 终端或BIOS的界面是简陋的, 让我们以为此时GPU还没进入工作状态(或电脑还没正式开启);

  • OS之下的桌面显示模块(某个程序), 负责将桌面渲染出来(如: 窗口, 或一些桌面上的文件), 在计算机开机OS启动时, OS的早期Loader就把负责渲染桌面的显示程序启动了(此处不是双击鼠标:)), 当这一步完成后(以及其它相关步骤), 我们就进入了桌面的世界;

  • 需要注意的是, 没有这个桌面, 计算机一样进行计算(计算发生在主板上, 而不是屏幕里), 而平常印象中的桌面的图形操作, 只不过是OS在后台将图形界面中的”事件/焦点框/数据”进行了一番计算并输出显示到屏幕上(如Excel表格, 或网页):

    一切发生在屏幕上的眼睛看到的表象, 都是计算机后台发生事情的一个子集而已(计算机是个狠人, 它启动程序是将可执行的ELF文件加载进内存的, 而不是靠双击图标的:D), 另外, 即便用户在屏幕上啥也不动, 计算机后台的时钟可是马不停蹄地在GHz震荡, 这不是人体心脏或是手臂的抖动, 而是电子世界的震荡, 无法感同身受, 不能试着理解;

  • 打个比喻, 旧式终端界面好像计算器一样(进行简单计算, 以及黑白像素液晶显示器), 而现在的桌面电脑, 则高大上很多, 好像计算器升级了一番, 换上了彩色显示屏, 除了进行加减乘除, 还能显示图形(计算像素);

  • 以上这一切的便利, 都在C编译器(以及其服务对象UNIX)出现后变得大大加速(读高级语言的英文单词总比读汇编逻辑方便)及不可理解了(程序员都转向高级编程语言的学习了(商业/社会发展驱动), 底层黑盒触碰得愈发少了):

    有了C和UNIX, 啥硬件开发都用C了(驱动程序), 啥语言开发也用C了(因为C有最基础的将代码转换到汇编/机器码的编译”模块/程序”), 但可以说, C没什么能摆脱CPU架构的特点(其它语言也不会有, 包括汇编和BIOS), 但是符合社会生产规律的: 有一个好用的工具(即C), 难道还会去用效率更低/更反直觉的工具吗(汇编, 指开发效率上), 随着C这座大厦越筑越高, 想要重新来的概率, 是如下极限了: $\displaystyle \lim_{x \to 0}x$;

OS中的虚与实:

文件是实, 桌面是虚

内存中的光标位置是实, 显示屏上的光标是虚

提问: 一个OS系统有了桌面界面如何理解终端的存在?! : 这个问题貌似很有挑战, 其实则是一个坑.

Reference:

  1. 百度百科, X Window, ref;

  2. Cnblogs, X Window的奥秘, ref;

  3. Csdn, X Window的理解, ref;

  4. Csdn, 正确理解 X Window, ref;

  5. Csdn, X Window实现原理, ref;

  6. Csdn, 技术扫盲: X窗口系统, ref;

  7. Csdn, Linux图形窗口这家子, Ref;

  8. Csdn, X Window系统窗口显示原理, Ref1, Ref2;

  9. Csdn, 认识X Window窗口管理器, Ref;

  10. Csdn, startx及xinit介绍, Ref;

开学报到:

程序: 高级编程, CPU, 汇编.

Hexo_mathjax:

https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=mathjax%20hexo&oq=mathjax&rsv_pq=e805b1a70005b287&rsv_t=3b23b0VzemdKtU7Laq6fJcv5F0PYXcSN7ZctD5EqR0Se1wWI5cd3xagfyHQ&rqlang=cn&rsv_enter=1&rsv_sug3=3&rsv_sug1=3&rsv_sug7=000&bs=mathjax

https://blog.csdn.net/u014630987/article/details/78670258

https://www.google.com/search?q=hexo+mathjax%E9%85%8D%E7%BD%AE&sa=X&ved=2ahUKEwjxn8yB77jjAhVUE4gKHfFYBOIQ1QIoAHoECAoQAQ&biw=1680&bih=939

https://i-m.dev/tools/

numpy与scipy:

https://docs.scipy.org/doc/

https://blog.csdn.net/tymatlab/article/details/79009618

https://www.baidu.com/s?ie=UTF-8&wd=TypeError%3A%20Cannot%20read%20property%20%27utcOffset%27%20of%20null

https://blog.csdn.net/buppt/article/details/78016407

Unix - Shell

首先, 要讲一下关于Shell的命名问题: Shell为什么叫(Shell)?! 简单说来就是, shell这层壳就是套在操作系统外面的一个机制, 有了shell, 操作系统的内核就可以将自己与外部使用环境隔离开来, 保证了内核的安全, 故取名这么一个东西叫shell也是很正确了(维基百科: “普通意义上的shell就是可以接受用户输入命令的程序“, Ref).

在使用中, shell的工作机理也是这样的: 用户输入命令行语句(shell脚本语句)或者执行一个shell脚本, 由终端(在Mac中是Terminal)这个软件将命令行语句传递给相应执行程序, 从而达到运行某个程序的目的. 当然, 我们可以双击某个执行程序运行该程序, 但这是图形界面的运行方式, 在1970或者1980图形界面还不像现在这么流行的年代, 启动程序的方式是通过终端来进行的, 而且, 双击打开某个程序的话, 怎么传递参数给这个程序?! 此外, 使用鼠标操作程序的方式在现在看来应该是打开”应用/软件”吧(不应该叫程序: 程序和程序猿不是很搭吗:D).

尽管有很多shell的存在(如: ash, bash, dash, ksh, zsh), 但上述shell的机理不应有区别, 不同shell的区别应当是语言(shell script)风格方面的, 而不是shell功能定位和主旨上的.

要命的配置文件 在使用高级编程语言进行编程活动时, 时常会遇到引用库不存在的问题, 这类问题的原因也时常和包含路径有关($PATH):

Shells read configuration files in various circumstances. These files usually contain commands for the shell and are executed when loaded; they are usually used to set important variables used to find executables, like $PATH, and others that control the behavior and appearance of the shell. The table in this section shows the configuration files for popular shells.

上述引用讲了几个要点: 1.shell会读取配置文件(如: ~./.bash_profile), 2.这些配置文件中包含的是shell可执行的脚本命令(当它启动时), 3.通常会在这些配置文件中设置诸如$PATH这样的重要变量(以及其它用于控制shell行为和外观的变量), 4.如下表格(此处未引用)显示了一些常用shell的相关配置文件.

可知, shell去读取某个配置文件是一种固定模式, 当一个系统中的shell终端确定时, 这个将要读取的配置文件就确定了, 不需要认为地再去设定. 联想到Mac(或类Unix系统)中根目录下的一些文件, 如: usr, bin, sbin, opt, etc, 这些文件夹也是固定命名的(由于历史原因! 历史是没法改变的! 时光是无法倒流的!), 无论Mac的图形界面设计如何迭代, 这些隐藏的文件的命名是永远变不了了(好丑的命名:D), 谁叫Mac是类Unix且是”私有”的系统呢.

下面, 附”Unix shell”图几张, 都还蛮有意思的:

01_Unix命令_1.png

图1. Unix命令_1, Reference#3

02_Unix命令_2.png

图2. Unix命令_2, Reference#3

03_Vi命令.jpg

图3. Vi命令, Reference#3

(后记: 搜索时尽量用Google, 百度也可以结合使用, 不过光百度的话, 会让我失望的(或者反之亦然?! 不过就这几次的经验来看, Google的惊喜还是不错的))

Reference

  1. 维基百科, Unix shell, Ref_中文 => Shell_Book, Ref_英文;
  2. 维基百科, PATH(variable), Ref);
  3. Reddit, Unix Shell Posters Re-made, Ref;

其它参考

  1. 关于Terminal, Console, Shell和Command Line的区别释疑, 可参考: Ref, 含图片示例, 或另一个类似提问[Ref];
  2. 萨里大学(University of Surrey)关于Unix的介绍(UNIX Introduction), Ref;
  3. Mally.stanford.edu关于基本Unix命令的讲解, Ref;