Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >计算机基础1-从计算机组成到程序性能

计算机基础1-从计算机组成到程序性能

原创
作者头像
jadeCarver
发布于 2021-01-07 12:34:56
发布于 2021-01-07 12:34:56
4880
举报
文章被收录于专栏:CS成长之路CS成长之路

本系列计划从计算机组成出发,探索现代计算机存储体系,以及各种使用场景中,计算机如何使用存储技术来提升计算能力。

从计算机组成到程序性能 几种典型的计算机存储介质 编码——背后的劳作者 云时代的存储技术

计算机的核心功能是数据计算。

若想要完成复杂的计算,例如游戏场景、文字处理等,就必须要有数据的存储。以最早的计算工具算盘为例,排列成串的算珠即是它的存储介质。现代计算机都是基于冯诺依曼结构,这套模型的背后,指出了将存储设备与中央处理器分开的架构,也就是说,存储与计算的指令系统是分开的。

程序员们依托于计算机构建庞大的软件世界,当透过代码的表象,一个程序是如何跑起来的?

一个程序的执行之路

程序员小张是一个前端工程师,他写了一段优雅的 JS 代码:

代码语言:txt
AI代码解释
复制
const a = 1;
const b = 2;
console.log(a + b);

放到浏览器中执行,成功地获得了他期待的效果。他很好奇,这背后到底发生了什么事。

经过一番探究,他大概理解了这个过程:程序最开始存储在磁盘上。JS 作为一门高级编程语言,这串代码人类可读,我们自然可以说它们是优雅的,但计算机不吃这一套,高级语言编写的代码无法直接被计算机执行,首先得经过一系列的编译过程,将其转换为机器语言,也就是二进制位串。或者,用高级话讲,可以称作比特流。所以小张特意去温习了编译原理的东西,原来,一段程序由高级语言到二进制流,主要经过了以下的几个步骤:词法分析、语法分析、语义检查、代码优化和生成字节码。

  1. 词法分析(Tokenizing/Lexing):也就是分词,将代码切分为最小的语义单元,在小张这串程序中,const,a,=,1,都是一个个词法单元(token)。
  2. 语法分析(Parsing):这个过程是将词法单元按照程序逻辑逐层嵌套的程序结构树,这个树被称为抽象语法树(Abstract Syntax Tree, AST)。
  3. 语义检查:当生成抽象语法树之后,可能会出现一些类型不匹配造成的编译错误,这个时候,就需要进一步进行语义检查,语义检查的重要任务之一就是类型检查,例如函数的形参与实参类型是否匹配。当然 JS 作为弱类型语言,就无所畏惧啦。
  4. 代码优化和生成字节码:这个阶段负责将 AST 转化为可执行的机器语言。JS 作为宇宙级语言,它在不同的环境中会有不同的生成过程。例如最常见的 v8 引擎,v8 引擎有专门的优化编译器将 AST 优化编译为机器语言。

终于,小张优雅的代码在经过一系列的骚操作后,变成了他不认识的样子(机器码),事实上,计算机中的万事万物,都是由一串比特表示的,在计算机电路的最底层,是由大量的逻辑门构成,二进制的0和1分别对应逻辑门的两种状态。更细致地来说,我们的代码最终都被描述为一系列机器语言指令。

对于计算机来说,这才是它熟悉的味道,因为,它终于可以开始执行了!

此时,我们的源代码已经被编译成可执行的二进制文本文件,并被存放在磁盘上。向计算机发出执行的命令之后,计算及内部一些我们耳熟能详的打工人们行动起来。

编译好的源程序码会被陆续地经过系统总线(代码的高铁系统)运输到主存。主存是程序的临时存储空间,可以理解为一个线性的字节数组,每个进入这里的数组都会为其分配一个唯一的地址。

接下来,处理器(CPU)登场了。CPU 的核心是大小为一个字的存储设备(寄存器)组成的,寄存器永远指向主存中的一条机器语言指令。处理器根据指令级架构模型(我们常讲的ARM和x86架构)来有序地执行指令。每执行完一条指令,就会更新寄存器,使其指向下一条指令。当然,CPU中还有其他的部件,来辅助计算,例如ALU(算术逻辑单元)来计算新的数据和地址值。如此反复运行这个周期,一段程序会被完整地执行。如果要实现更复杂的人机互动,就需要计算机的其他部件的参与,例如I/O设备、图形设备器、网卡适配器等等,这些适配器都是一些外部设备与计算机总线相连的接口。

一个与人体的类比

现在我们大概理解为什么寄存器所在的位置被叫做中央处理器,因为,计算机的计算核心就在这里。从一定意义上讲,计算机的构成和世间的万事万物都有相似之处,整体采用一种分层理念。以人体做类比:

CPU就像人的大脑,人身体的养料通过血管运输到大脑,计算机程序的执行指令通过总线到达CPU。

人体通过感官系统与外界交互,计算机通过各类输入输出设备与外界互联。

人体通过脂肪来存储养料,计算机则需要存储设备来存放数据。

而他们的各个部分又是如此地不可分割,相互协作之下,才能保证整个系统的平稳运行。

下面这张图描述了一个典型的计算机硬件系统组成:

一个典型计算机系统的硬件组成
一个典型计算机系统的硬件组成

计算机的性能卡点在哪里

在以上的篇幅,我们粗略地介绍了一段程序是如何被计算机执行的。但对于程序员来讲,写出一个可执行的程序只是最低要求,我们希望程序能够更高效地执行。接下来,我将从程序员的角度来剖析计算机是如何设计来加速计算过程的,以及,目前计算机的性能瓶颈在哪里。

计算机的性能瓶颈

CPU 是否够快,一般被视为衡量计算机的运行效率的重要标准之一。但实际上,随着半导体技术的进步,CPU 的处理效率越来越快,已经不再是限制计算机性能的瓶颈。

与CPU的处理效率高速发展的相比,主存的处理速度却提升缓慢,也就是说,主存限制了CPU的运算能力。就好比,天龙八部中的王语嫣,作为一个行走的武功百科全书,对于各类武功了如指掌,但内功过差,没法上阵对敌。所以,影响程序执行性能的瓶颈越来越明显。

越大的存储器,其执行效率越慢。例如,一个寄存器文件一般只有几百字节,主存可能有数G,而外部存储或者硬盘可能达到数百G,甚至更大。可以在这里看到计算机世界中一些执行速度对比:

image-20201202090611071
image-20201202090611071

这也是著名的冯诺依曼瓶颈所指出的:为了执行指令,需要花费大量时间从存储器中取出来。开始的时候,源代码被放到磁盘上,程序加载时,需要将之复制到主存。程序运行时,又需要按一条一条指令复制到处理器。这部分“在路上”的时间占去了程序的大部分运行时间。

为了缓解这一状况,高速缓存(cache memory)被设计出来。缓存区域用来存放处理器近期可能会被用到的信息。

多层缓存——计算机系统的努力

现代计算机的存储器结构的主要思想是添加高速缓存层(cache),以提高计算机的计算速度。具体做法是,在执行效率很快的处理器和较慢的主存之间插入一个更小更快的存储设备,这部分就是缓存区。这种设计的理念是,下一层作为上一层的高速缓存,L1是寄存器文件的高速缓存,L2是L1的高速缓存,L3是L2的高速缓存,以此类推。当前层会优先从下一层去获取是否有需要的信息,极大避免了消耗在路上的时间。例如,处理器每次执行一条指令,可能只有几个字节,如果每次都需要到硬盘上读取,则耗时太多!

所以说,现在计算机的存储结构呈现为一个层级结构,从上至下,设备的访问速度越来越慢,容量越来越大,造价越来越便宜。简单来说,现代计算机在处理器和主存之间有三层(L1-L3)高速缓存结构,它们使用造价昂贵的SRAM存储。同样地,由上往下,每层的存储空间越大,读取速率越慢。他们从上图可以看到,L1缓存层与主存的引用速率相差100倍。

img
img

事实上,这种缓存的理念的计算机的世界中随处可见。例如,浏览器和 HTTP 的多重缓存机制,RedisCDN 等,都可以找到缓存的影子。

程序的局部性

程序运行的效率或者性能,是程序员们最关注的主题之一。对于程序员来说,程序执行的最大开销就是数据的复制过程

程序是指令和数据的结合。数据是计算的原材料,指令是计算的操作命令。程序员为数据起了名字,也就是变量。计算机中所有的数据最底层的表现形式都是二进制串,这些数据在计算机各个模块之间流动起来,执行任务。

如何衡量一个程序的好坏?

一方面,其需要尽可能正确地工作(bug 在所难免);另一方面,其要尽可能快地运行。在今天这个世界,写程序已经不是一些 geek 的玩具,而是承载着无数商业应用的软件工程,所以,对于程序的评价,在追求运行速度的同时,必须要注意可维护性,或者说,代码的可读。也就是说,对于程序员来说,必须要在程序的运行速度和可维护性之间做好权衡。

计算机程序倾向于引用邻近于其他最近被引用过的数据项的数据项,或者最近引用过的数据项本身。这就是计算机的局部性原理

局部性原理经常被解释为两种类型,时间局部性:一个被引用过的一次的内存位置很可能在不远的将来多次被引用。空间局部性:如果一个内存位置被引用过一次,可能在不远的将来引用附近的一个位置。

局部性良好的程序运行得更快。多层存储层级结构之所以有效,正是局部性原理的一个表现。符合局部性的数据被缓存起来,再次被读取操作时,将获得更高的效率。高速缓存中放置从主存中取出来的缓存数据,主存中存放着磁盘中最近被引用的数据块,各种缓存技术都是局部性的应用,例如浏览器的本地缓存,会被优先应用等。

编写性能友好的程序

如果计算机硬件组成对于局部性原理的使用,程序员在编写软件的时候,要善于编写高速缓存友好的代码。宏观上来说,善用之前所讲的浏览器缓存、Redis缓存等技术。微观上来说,在编写代码时,需要注意局部性友好。在《深入理解计算机系统》一书中提到了以下两个技巧:

将你的注意力集中在内循环上,大部分计算和内存访问都发生在这里 通过按照数据对象存储在内存中的顺序,以步长为1来读数据,从而使得你的空间局部性最大。 一旦从存储器中读入了一个数据对象,就尽可能多地使用它,从而使得程序中的时间局部性最大。

第2点中提到的步长为1,可以理解为按顺序、连续地对某一个变量的引用。

参考

计算机的存储系统

性能之殇:从冯·诺依曼瓶颈谈起

访问局部性

【书】深入理解计算机系统

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
计算机组成原理之机器
1.1 计算机系统概论 1.1 计算机系统简介 把感应器嵌入和装备到电网,铁路,桥梁等各种物体中,并且被普遍连接,形成所谓“物联网”,然后将“物联网”与现代计算机网络联合起来,实现人类社会和物体实体的整合,形成智慧地球。 计算机系统由硬件和软件组成。软件分为系统软件和应用软件,前者包括操作系统,语言处理程序,服务性程序等。 计算机编程的层次结构:微指令系统->机器语言->操作系统->汇编语言->高级语言,前两者属于硬件编程层次。 计算机体系结构指的是程序员所能看到的计算机系统的属性,概念性的结构和功能特性(
潘成涛
2018/01/18
8300
计算机组成原理之机器
《深入理解计算机系统》(CSAPP)读书笔记 —— 第一章 计算机系统漫游
  接下来的计划是补充下操作系统和计算机组成原理相关的知识。从《深入理解计算机系统》这本书开始吧,系统学习下《深入理解计算机系统》这本书,还有9个Lab可以做下,以便加深理解。初步计划一周一章(不知道行不行),争取在放寒假前做完这些。
嵌入式与Linux那些事
2021/05/20
7000
《深入理解计算机系统》(CSAPP)读书笔记 —— 第一章 计算机系统漫游
计算机系统的漫游
用c语言编写的hello程序实际上是由0和1组成的位(也叫比特)系列,8位被组织在一起叫做字节 . 由ASCII字符构成的文件叫做文本文件,所以的其他文件都称为二进制文件。
code-child
2023/05/30
1900
计算机系统的漫游
计算机组成原理面试常见问题总结
本文记录了一些计算机组成原理面试常见问题,本意用于考研复试,以下面试题为网上整理的问题以及自己加入的一些问题,答案仅供参考!
EmoryHuang
2022/08/24
2K0
计算机组成原理面试常见问题总结
深入理解计算机系统系列【计算机系统漫游】
操作系统原理是计算机行业基本功,想要成为一名计算机领域的专业人士,必不可少要打好基础。最近打算重点读一读《深入理解计算机系统》这本书,回顾和提升自己对计算机和操作系统的理解。这是第一篇:【计算机系统漫游】。【计算机系统漫游】主要通过跟踪hello程序的生命周期来开始对系统的学习----从它被程序员创建开始,到在系统上运行,输出简单的消息,然后终止。本文将沿着这个程序的生命周期,简要地介绍一些逐步出现的关键概念、专业术语和组成部分。
用户1432189
2018/09/05
6170
深入理解计算机系统系列【计算机系统漫游】
计算机组成基础
每天工作都在用计算机,玩游戏也在用计算机,移动互联网没有兴起之前撩妹/勾搭小哥哥也是用计算机,到底计算机是由什么组成的?
小末快跑
2019/07/03
7790
计算机组成-概述
冯诺依曼结构:运算器、控制器、存储器、输入设备和输出设备五大部件组成。现代计算机一般把控制器和运算器集成在一个芯片上,合称为中央处理器。 现代计算机一般以存储器为中心,使I/O操作尽可能绕过CPU,直接在I/O设备与存储器间完成,从而提高系统的整体运行效率。
千灵域
2022/06/17
2.4K0
计算机组成-概述
计算机组成原理总结及知识网图
https://download.csdn.net/download/weixin_42104154/14922915
全栈程序员站长
2022/09/05
6281
计算机组成原理总结及知识网图
计算机基础之计算机硬件系统
一.计算机硬件系统概述 所谓计算机硬件系统,就是指构成计算机看得见的,摸得着的实际物理设备。 常见的计算机硬件组成主要由下图各部件组成: 现代计算机的结构更复杂,包括多重总线。 简单打个比方,方便大家
用户1214487
2018/01/23
1.5K0
计算机基础之计算机硬件系统
计算机组成原理核心知识点总结&面试笔试要点[通俗易懂]
  作为一名计算机专业的学生,计算机组成原理、计算机网络、操作系统这三门课程可以说是专业核心基础课,是至关重要的,其内容是一名合格的coder所必备的知识集;非科班出身的程序员要是想要有所提升,也需要认真学习这三门课程,可以快速形成计算机知识的结构体系,理解计算机底层原理,在工作实践中可以借鉴优秀的设计;而且很多互联网公司在笔试和面试中都会涉及到这三门课程的知识点,因此我通过视频学习对这三门课程就行复习巩固,同时分三篇博客记录总结。
全栈程序员站长
2022/07/28
1.4K0
计算机组成原理核心知识点总结&面试笔试要点[通俗易懂]
计算机基础知识
           好多人觉得自己有点基础就都想着直接敲代码,觉得基础知识很容易,很简单,就不怎么用心去学。然而,我觉得基础知识很重要。就像盖一栋楼房一样,你先要打好地基,再去盖房。    
py3study
2020/01/17
5610
新名词|什么是「电源」程序员?
计算机系统(A computer system) 是由硬件和软件组成的,它们协同工作运行程序。不同的系统可能会有不同实现,但是核心概念是一样的,通用的。
cxuan
2020/03/27
3340
【系统架构设计师】计算机组成与体系结构 ④ ( 高速缓存 Cache | 冯诺依曼结构性能瓶颈 | 程序局部性原理 - 时间局部性、空间局部性 | 访问命中率 和 访问失效率 | 数据访问平均周期 )
冯诺依曼结构 的 性能瓶颈 : CPU 寄存器 的 存储速度 与 主存 ( 内存 ) 的 速度 不匹配 , 二者速度相差太大 , 严重影响计算机的性能 ;
韩曙亮
2024/07/14
3490
存储概述:计算机层次化存储体系概述
1946年,冯•诺依曼提出了以存储程序为核心的计算机模型,该计算机模型一直沿用至今。通常称该计算机模型为冯•诺依曼模型(结构),将采用该思想设计的计算机为冯•诺依曼计算机。
Janesong
2024/08/30
2260
图解计算机的存储器金字塔
在计算机组成原理中的众多概念中,开发者接触得最多的还是内存、硬盘、虚拟内存、CPU 缓存这些概念。这些概念有一个更为抽象的表示 —— 存储器,它是冯 · 诺依曼计算机体系中的五大组件之一,用于存储程序和数据。
用户9995743
2022/12/22
8390
图解计算机的存储器金字塔
【计算机组成原理】计算机系统层次结构——计算机硬件
在上一篇内容中我们介绍了计算机的发展历程,在这个过程中,我们了解到了计算机发展的四个时期:
蒙奇D索隆
2024/09/07
6830
【计算机组成原理】计算机系统层次结构——计算机硬件
探索计算机存储层次体系:从寄存器到磁带
在日常使用计算机的过程中,我们或多或少都接触过硬盘、内存等存储设备。但是,你是否曾经思考过这些存储设备之间的关系和区别?它们是如何协同工作,为我们提供流畅的计算体验的呢?这就涉及到一个核心概念——计算机存储层次体系。本文将详细剖析计算机存储层次体系的构成,运作方式以及具体应用。
码事漫谈
2024/12/23
2040
计算机组成原理概述
计算机硬件是构成计算机系统各功能部件的集合。是由电子、机械和光电元件组成的各种计算机部件和设备的总称,是计算机完成各项工作的物质基础。计算机硬件是看得见、摸得着的,实实在在存在的物理实体。 计算机软件是指与计算机系统操作有关的各种程序以及任何与之相关的文档和数据的集合。其中程序是用程序设计语言描述的适合计算机执行的语句指令序列。 没有安装任何软件的计算机通常称为“裸机”,裸机是无法工作的。如果计算机硬件脱离了计算机软件,那么它就成为了一台无用的机器。如果计算机软件脱离了计算机的硬件就失去了它运行的物质基础;所以说二者相互依存,缺一不可,共同构成一个完整的计算机系统。
黄规速
2022/04/14
1.4K0
计算机组成原理概述
操作系统学习笔记-计算机系统概述
从最顶层看,一台计算机由处理器(CPU,包含运算器、控制器)、存储器以及输入/输出部件组成。
花猪
2022/02/16
7460
操作系统学习笔记-计算机系统概述
02.计算器存储器的原理
import java.util.HashMap; public class StudentHashMapExample { public static void main(String[] args) { // 创建一个哈希映射 HashMap<String, Integer> studentMap = new HashMap<>(); // 添加学生信息到哈希映射 studentMap.put("Alice", 85); studentMap.put("Bob", 92); studentMap.put("Charlie", 78); studentMap.put("David", 90); // 获取学生信息 int aliceScore = studentMap.get("Alice"); System.out.println("Alice's score: " + aliceScore); // 更新学生信息 studentMap.put("Alice", 88); aliceScore = studentMap.get("Alice"); System.out.println("Updated Alice's score: " + aliceScore); // 删除学生信息 studentMap.remove("Bob"); System.out.println("Bob's information removed."); // 遍历学生信息 for (String name : studentMap.keySet()) { int score = studentMap.get(name); System.out.println(name + "'s score: " + score); } } }
杨充
2024/08/01
1160
推荐阅读
相关推荐
计算机组成原理之机器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档