速通CSAPP(一)计算机系统漫游入门

CSAPP学习

前言

一门经典的计组课程,我却到了大四才学。

anyway,何时都不会晚。

博主参考的教程:本电子书信息 - 深入理解计算机系统(CSAPP) (gitbook.io),非常感谢作者的整理。

诚然去看英文版可以学到更多,不过一边翻译一边看的过程我觉得还是效率不高的,所以还是选择中文。

博主之前有一定的计算机基础,所以对一些简单概念可能跳得比较快,这里建议读者不懂的地方不要气馁“为什么这里三两句就讲掉了,但是我还没懂”。建议多多发掘自我检索能力,Search the Fxxking Web (STFW) 是计算机专业同学的一大重要能力。

Ch1. 计算机系统漫游

程序运行前4个阶段

相信尝试过一定编程学习的同学们都有过写、运行 helloworld 的经历。可能是用 Dev C++,VSCode,CLion 等 IDE,也可能是自己在命令行执行编译运行语句,本质都是一样的。

那么写了一个 helloworld.c,这个程序是怎么运行起来的呢?

首先计算机能直接运行的都是二进制文件,01010101110101……类似这样的文件。但是要是说让我们用这种语言(机器语言)编程,效率极低而且大概率会疯掉。

汇编语言是一种为了解决这个问题而诞生的低级语言,相对好理解一些,可以转换成机器语言。不过还是面向计算机的语言,编程习惯主要也是按照计算机的思维走,也比较难。

c语言是一种高级语言,是我们人类一定程度上能理解的编程语言,可以转换成汇编语言,再转成机器语言,供计算机运行。

gcc -o hello hello.c

这条命令行语句意思是用 gcc 翻译工具,把 hello.c 翻译成目标输出文件(output)hello,得到的可执行文件就是 hello。

翻译流程如下:

image-20231126214148576

预处理:把文件中的注释信息去掉(注释信息是给人看的,对计算机运行没啥帮助),把头文件展开(其实头文件 #include #define 这些就是对一些格式内容的拷贝),得到 .i 文件。

编译:把高级语言翻译成汇编语言。相同的程序用不同高级语言写,经过编译器后,得到的汇编语言是相同的,也就是计算机最终执行的具体行为都是一样的。感兴趣同学可以了解一下编译和翻译两种高级语言转汇编语言的方式。

汇编:把 .s 汇编文件转为 .o 目标文件,目标文件也是二进制形式。但是缺少一些外部链接的库,暂时不能执行(比如 printf 函数是在 printf.o 文件中定义的,我们自己没定义,所以不能自己直接用,需要外链 printf.o 文件才能使用)。

链接:如上所述,最终生成一个可执行的目标程序。

好现在是可以理解高级语言的作用(让我们不用理解计算机具体运行方式,就能较为简单的编程,生成可执行文件)。但是我们还是需要学习一下底层的编译、汇编等原理的:

  • 因为理解底层具体实现后,我们才知道怎样编写的程序运行更高效(同一个问题有许多解法,可以写许多种程序,比如 switch case 和 if else if,但是并不是能解决正确性的程序就是好程序了,我写一个跑一年才出结果的代码和跑1小时就出结果的代码价值也是完全不同的)。
  • 对程序理解更深,出现问题时我们也知道如何排查,bug 不全是只有中英文字符那种程度的哦。
  • 甚至有一些安全性问题是通过对底层原理进行攻击的。

CPU硬件运行方式

程序翻译成汇编语言类似这样:

main:subq $8, %rsp       ; 通过从栈指针(rsp)减去8字节,为栈分配空间。movl $.LC0, %edi    ; 将字符串".LC0"的地址加载到目标寄存器%edi中。call puts           ; 调用puts函数,该函数可能打印%edi寄存器指向的字符串。movl $0, %eax        ; 通过将0移动到%eax寄存器中,将返回值设置为0。addq $8, %rsp       ; 通过将8字节添加到栈指针(rsp),释放栈上的空间。ret                 ; 从main函数返回。

不用看懂。可以看到按照计算机思维,这个程序被拆成了这么多条要执行的指令。CPU 执行程序的时候就是一条条指令执行的。

具体是怎样执行?下图是 计算机基本组成的结构图。计算机五大组成部分:CPU(运算器+控制器),内存,输入,输出。

1701006354660

总线:在各个设备之间传输数据用。

输入设备:把信息输入给电脑的一些方式,比如键盘打字,鼠标点击,光盘U盘,我们写的程序存在磁盘上。

输出设备:电脑把信息输出给我们的方式,比如可以看到的显示器。输入输出设备统称 IO 设备。

主存:也叫内存,程序从磁盘里拿出来放到主存里运行。内存是衡量计算机运行快不快的一个重要指标因为内存小了每次能拿一小部分程序进来运行,再拿下一部分,效率比较低,内存大了磁盘和内存之间交互可能相对就快很多(磁盘里的内容往内存拿是比较占时间的)。

CPU:从主存里面拿一个个字节的数据进行处理。PC 是一个指针指向当前要拿的数据的位置;首先从 PC 所指向的主存地址中加载几个字节到 CPU 寄存器里,把寄存器中的内容复制到 ALU 中进行操作,比如取到了a和b的值算a+b;然后可能需要把一些数据存储写回到主存中,比如让 c=a+b,c的值变了,那么我们可能就需要把新值写回到主存中c的位置;最后 PC 跳转,指向下一部分要取的字节的位置。重复上述操作直到程序执行完。

比如想跑一个 helloworld 我们经历了这些步骤:

  1. 鼠标键盘输入,写了一个 helloworld 程序并点击运行或 shell 输入运行语句 ./helloworld。我们输入的运行指令也是先被放到主存,然后被 CPU 寄存器文件读取,CPU 解析后明白我们是想执行 helloworld 文件,然后再下指令从磁盘中取 helloworld 程序到主存里运行。
  2. helloworld 程序被加载到主存中(虽然 CPU 是计算机的大脑,中控中心,但是这里磁盘数据不用经过 CPU 可以直接给主存是利用了 DMA 技术),CPU 再取主存中的数据进行指令解析,执行。
  3. CPU 解析指令直到我们是想在终端打印 helloworld,于是驱动显示器输出设备输出显示 helloworld。

Cache 缓存

CPU 去主存取指令,和去磁盘取指令,其实都有一定的时间开销(去磁盘开销更大)。我们可以在 CPU 内部临时存一些近期可能要访问到的内容,这样当访问到这部分内容的时候不需要每次都去主存去磁盘拿,在自己这里就找得到就快很多。比如c=a+b;c=a+b;c=a+b;c=a+b; 执行这个指令,如果第一次执行的时候 CPU 猜测,a和b的值后面会不会还要用到,我先在缓存里存一下以备不时之需。第二次执行的时候可以直接拿到本地缓存 cache 中存储的 ab 值进行运算,不用去磁盘里再取一次了,第三次第四次也是,这样就比较节约时间开销。

1701007513400

当然缓存大小有限,以此来保证 CPU 芯片大小不会太大和缓存中查找不会太慢。因此我们要设计一些缓存存储算法来决定哪些内容优先被存入缓存,这个后面再细讲。

缓存结构其实是这样的,著名的缓存金字塔:

1701008756610

上面一层是下面一层的缓存。

操作系统

operating system,了解一些的同学可能知道,比如win系统,mac系统,linux系统,这玩意啥用处呢。主要是实现对资源的分配管理。

1701009194351

比如我qq应用程序,要调用键盘,调用摄像头,要调用键盘……首先应用程序直接去操作这些底层的 CPU,主存,IO 都比较麻烦,而且也不安全(比如qq崩溃异常状态下去调用这些设备)。操作系统负责中间管理,抽象出这些设备的接口供应用程序调用,也保护硬件不被失控应用程序滥用。

操作系统的抽象如下:

1701011455062

进程

一个正在运行的程序。操作系统会协调多个进程交错执行,比如我现在电脑上开着微信 浏览器 Typora,内核不停地切换这些进程的执行而我感觉不到。

进程切换需要保存当前进程状态,切换到下一个进程的状态继续运行,这个状态叫上下文 context。

1701011886237

一个进程可能包含多个线程,他们共享这个进程的资源。

GPT:

1701012069165

虚拟内存

操作系统让多个进程互不干扰的使用主存,对每个进程来说他们只看得到自己的主存占用范围,感觉好像只有自己在占用主存,这就叫虚拟内存。

1701012340917

如图是主存中的组成,从下往上地址逐渐增大。

内核虚拟内存:给操作系统用的。

用户栈:比如程序里的函数,存到这里入栈。

共享库内存:比如 printf 这种共用库。

堆:比如 malloc 申请的空间,存在这里,也是多个程序共用。

数据:存放程序数据。

虚拟内存具体实现方法后面讲解。

文件

字节序列。所有 IO 设备都可以看做是文件,我们可以往文件里读写数据进行 IO 操作。这样我们对磁盘进行读写的时候其实我们并不关心具体读写 IO 行为,我们只需要往磁盘文件夹里读写文件即可。

网络通信

其实网络也类似一个 IO 设备,我们给网络适配器写入数据流,网络适配器发送给另一台主机。

比如下例,好处在于我们可以把程序存在服务器上,在服务器上跑,我们只需要发送简单指令。比如学习深度学习,不用自己非得买一个牛逼电脑,可以租牛逼服务器(服务器其实也算是一种电脑,和我们的客户端电脑没啥区别)。

1701012804553

重要概念

Amdahl 定律

计算提升系统某一部分性能对整个系统所带来的效果。

α是某一部分在整个系统中占的比重,k是这部分的性能加速了多少。S是最终对整个系统提升的加速效果。

1701013272748

比如α=60%,k=3,这一部分提升了3倍速度,但是对整体速度的提升是1.67倍,可见想要提升系统整体速度,需要提升系统中大部分的速度。

并发 并行

并发:一个系统同时运行多个活动。

并行:利用并发来加速程序运行。

线程级并行

进程中多个任务的切换。

单处理器系统:模拟并发,即实际上是不断切换。

多处理器系统:确实可以并发运行,也可以加速用多线程方式写的单个程序。

超线程:也叫同时多线程,允许单核 CPU 执行多个控制流,多个控制流共享执行单元。比如单处理器切换线程,需要保存当前状态,切换 pc 指针,寄存器值……而超线程多个核对 pc,程序计数器等有拷贝,使得切换的时候不用那么麻烦,比如常规单处理器切换可能需要20000个周期,超线程一个周期就能切换。

指令级并行

有些系统硬件支持把一条指令拆成多个任务同时处理。

当指令周期小于1的时候(一个 CPU 时钟周期可以执行平均1条以上的指令)系统被称作超标量系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/175879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【开源】基于Vue和SpringBoot的木马文件检测系统

项目编号: S 041 ,文末获取源码。 \color{red}{项目编号:S041,文末获取源码。} 项目编号:S041,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 木马分类模块2.3 木…

软著项目推荐 深度学习中文汉字识别

文章目录 0 前言1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习中文汉字识别 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐&#xf…

【Vue】Linux 运行 npm run serve 报错 vue-cli-service: Permission denied

问题描述 在Linux系统上运行npm run serve命令时,控制台报错: sudo npm run serve project50.1.0 serve vue-cli-service serve sh: 1: vue-cli-service: Permission denied错误截图如下: 原因分析 该错误是由于vue-cli-service文件权限不…

线性转换函数S_RTR(SCL和ST代码)

模拟量转换函数S_ITR详细公式和算法源代码请查看下面文章链接: PLC模拟量输入 模拟量转换FC S_ITR_博途模拟量转换程序_RXXW_Dor的博客-CSDN博客文章浏览阅读5.4k次,点赞4次,收藏7次。模拟量采集、工业现场应用特别广泛、大部分传感器的测量值和输出信号都是线型关系,所以…

Rocky Linux 9.3 为 PowerPC 64 位带回云和容器镜像

RHEL 克隆版 Rocky Linux 9.3 今天发布了,作为红帽企业 Linux 发行版 CentOS Stream 和 Red Hat Enterprise Linux 的免费替代版本,现在可供下载。 Rocky Linux 9.3 是在 Rocky Linux 9.2 发布 6 个月之后发布的,它带回了 PowerPC 64 位 Lit…

4D雷达目标检测跟踪算法设计

1.算法流程 4D雷达点云跟踪处理沿用3D毫米波雷达的处理流程,如下图: 从接收到点云开始,先对点云做标定、坐标转换、噪点剔除、动静分离,再分别对动态目标和静态目标做聚类,然后根据聚类结果做目标的特征分析和检测等&a…

leetcode42接雨水问题

接雨水 题目描述 题目分析 核心思想: 代码 java版本: package com.pxx.leetcode.trapRainWaterDoublePoniter;public class Solution1 {public int trap(int[] height) {if (height.length 0) {return 0;}int n height.length;int left 0;int righ…

LabVIEWL实现鸟巢等大型结构健康监测

LabVIEWL实现鸟巢等大型结构健康监测 管理国家地震防备和减灾的政府机构中国地震局(CEA)选择了七座新建的巨型结构作为结构健康监测(SHM)技术的测试台。这些标志性建筑包括北京2008年夏季奥运会场馆(包括北京国家体育场和北京国家游泳中心)、上海104层的…

Eureka简单使用做微服务模块之间动态请求

创建一个eureka模块,引入eureka 为启动项加上EnableEurekaServer注解 配置信息 orderService和userService的操作是一样的 这里以orderService为例: 引入eureka客户端 加上 LoadBalanced注解 配置 orderService和userService都配置好了之后 启动 这样我们在http://localhos…

Python实现FA萤火虫优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法(Fire-fly algorithm,FA)由剑桥大学Yang于2009年提出 , …

【读懂AUTOSAR】DoIP模块(1)-- 使用场景和链接的建立规范

引子 --什么是?为什么使用DoIP? DoIP就是通过IP进行诊断的意思(Diagnostic Over IP)。我们熟悉的诊断都是通过CAN总线的啊,为什么要通过IP?IP是什么? IP就是Internet Protocol,就是”互联网协议“啦! 那DoIP就是通过互联网进行的诊断喽,也可以叫做“基于以太网的诊…

单片机学习11——矩阵键盘

矩阵键盘: 这个矩阵键盘可以接到P0、P1、P2、P3都是可以的。 使用矩阵键盘是能节省单片机的IO口。 P3.0 P3.1 P3.2 P3.3 称之为行号。 P3.4 P3.5 P3.6 P3.7 称之为列号。 矩阵键盘检测原理: 1、检查是否有键按下; 2、键的抖动处理&#xf…

阿里云服务器购买价格,云服务器与轻量应用服务器最新购买活动价格汇总

阿里云服务器租用价格是多少?不同时期阿里云服务器的租用价格不同,目前阿里云轻量应用服务器与云服务器优惠价格也有所变化,目前轻量应用服务器还是87元1年起,经济型e实例云服务器99元1年起,通用算力型u1云服务器643.6…

Flink CDC -Sqlserver to Sqlserver java 模版编写

1.基本环境 <flink.version>1.17.0</flink.version> 2. 类文件 package com.flink.tablesql;import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.flink.streaming.api.environment.StreamExecutionEnviro…

护眼灯值不值得买?国AA级别标准的护眼台灯推荐

在中国&#xff0c;近视人口占全国总人数的30%左右。中全国患近视眼的总数达到3.6亿。城市近视人口的近视率达到33%。其中&#xff0c;大学生的近视率是最高的&#xff0c;达到了75&#xff05;左右。中学生的近视率大约为50&#xff05;。在校佩戴眼镜的小学生比例为30&#x…

开始使用Spring Boot Admin吧-使用Nacos注册SBA

什么是 Spring Boot Admin&#xff08;SBA&#xff09;? Spring Boot Admin 是 codecentric 公司开发的一款开源社区项目&#xff0c;目标是让用户更方便的管理以及监控 Spring Boot 应用。 应用可以通过我们的Spring Boot Admin客户端&#xff08;通过HTTP的方式&#xff0…

GaussDB数据库SQL系列-触发器

目录 一、前言 二、触发器概念 三、GaussDB数据库中的触发器 1、语法格式 2、创建步骤 3、注意事项 4、附&#xff1a;表和视图上支持的触发器种类 四、GaussDB数据库中的示例 示例一、在GaussDB数据库中创建一个触发器&#xff0c;以便在插入新记录时自动将记录的创建…

论文笔记--Toolformer: Language Models Can Teach Themselves to Use Tools

论文笔记--Toolformer: Language Models Can Teach Themselves to Use Tools 1. 文章简介2. 文章概括3 文章重点技术3.1 Toolformer3.2 APIs 4. 文章亮点5. 原文传送门 1. 文章简介 标题&#xff1a;Toolformer: Language Models Can Teach Themselves to Use Tools作者&#…

堆详解(C语言实现)

文章目录 写在前面1. 堆的概念和性质1.1 堆的概念1.2 堆的性质 2 堆的实现2.1 堆结构的定义2.2 堆的初始化2.3 堆的插入2.3.1 向上调整算法2.3.2 堆的插入元素过程 2.4 堆的删除2.4.1 向下调整算法2.4.2 堆的删除元素过程 2.5 获取堆顶元素2.6 获取堆元素个数2.7 判断堆是否为空…

Spring Security 6.x 系列(6)—— 显式设置和修改登录态信息

一、前言 此篇是对上篇 Spring Security 6.x 系列&#xff08;5&#xff09;—— Servlet 认证体系结构介绍 中4.9章节显式调用SecurityContextRepository#saveContext进行详解分析。 二、设置和修改登录态 2.1 登录态存储形式 使用Spring Security框架&#xff0c;认证成功…