《深入立即计算机系统》书籍学习笔记 - 课程简介

news/2025/3/27 11:54:40/

Lecture 01 Course Overview 课程简介

文章目录

  • Lecture 01 Course Overview 课程简介
    • 概述
    • 不要抄袭
    • 书籍推荐
    • 课程内容
    • 帮助
    • 实验
    • 课堂纪律
    • 考试分数
    • 课程
      • 主题一:程序和数据
      • 主题二:内存层次结构
      • 主题三:例外的控制流程
      • 主题四:虚拟内存
      • 主题五:网络和并发
    • 课程实例
      • Great Reality #1
        • Example 1: Is x2 ≥ 0?
        • Example 2: Is (x + y) + z = x + (y + z)?
    • 代码
      • Great Reality #1
      • 二维数组行遍历效率远高于列遍历效率
    • 文档

概述

我的这些课程是通过B站视频学习《深入立即计算机系统》书籍学习所做的一些笔记。
分享出来希望和大家共同学习。

学习的资料:
【精校中英字幕】2015 CMU 15-213 CSAPP 深入理解计算机系统 课程视频
CS:APP主页
csapp 代码地址

不要抄袭

放弃复制黏贴,放弃搜索。

书籍推荐

  • Computer Systems: A Programmer’s Perspective(CS:APP3e)
    地址:http://csapp.cs.cmu.edu

  • The C Programming Language
    作者:Brian Kernighan and Dennis Ritchie
    C语言学习书籍。

课程内容

  • Lecture

    • Highter level concepts 高层级概念
  • Recitations 背诵
    所以不要忽略记忆。死记硬背也是基础。概念都不知道何来后面的。

  • Labs 实验
    课程的灵魂,编程只有不断的实践,遇到问题,解决问题,才会有所成长。
    背诵只是让你知道,实践才可以让你能够真正处理问题。

  • Exams 考试

帮助

网址:http://www.cs.cmu.edu/~123

实验

使用 Autolab 来做作业。

使用机器:
ssh shark.ics.cs.cmu.edu

课堂纪律

  • 可以带电脑,但是不要用于通信等其他与课程无光用途。
    认真听讲
  • 不考勤,自愿来不来

考试分数

考试和实验室分数各分50%,期中考试20%,期末考试30%

课程

主题一:程序和数据

  • 位操作,运算,汇编语言程序
  • C 语言控制和数据结构描述
  • 体系解雇和编译器

作业:

  • L1(datalab): Manipulating bits(操作位)
  • L2(bomblab): Defusing a binary bomb (拆除二进制炸弹)
  • L3(attacklab): The basics of code injection attacks(代码注入)

主题二:内存层次结构

  • 内存技术,内存层次,缓存,磁盘,局部性
  • 体系结构和操作系统

作业:

  • L4(cachelab): Building a cache simulator and optmizing for locality.
    构建缓存模拟器并优化局部性。
    学习如何在程序中利用局部性。

主题三:例外的控制流程

  • 硬件,进程,进程控制,unix 信号
  • 编译器,操作系统,体系结构。

作业:
L5(tshlab): Writing your own Unix shell
写一个自己的shell工具。
开始了解并发。

主题四:虚拟内存

  • 虚拟内存,地址转换,动态存储分配
  • 体系结构,操作系统

作业:
L6(malloclab): Writing your own malloc package
写一个自己的内存(malloc)包
获得对系统级编程的真实感受。

主题五:网络和并发

  • 高级/低级 I/O, 网络编程
  • 服务,web服务器
  • 并发,并发服务器设计,线程
  • I/O 多路复用与选择
  • 网络,操作系统,体系结构

作业:
L7(proxylab): Writing your own Web proxy
写一个自己的Web代理
学习网络编程和更多关于并发和同步。

课程实例

Great Reality #1

Example 1: Is x2 ≥ 0?

Ints are not Integers, Floats are not Reals

  • Example 1: Is x^2 >= 0 ?
    float:是的
    Int:
40000	*	40000		➙	1600000000
50000	*	50000		➙	??
Example 2: Is (x + y) + z = x + (y + z)?

Unsigned & Signed Int’s: Yes!
Float’s:

(1e20	+	-1e20)	+	3.14	-->	3.14	
1e20	+	(-1e20	+	3.14)	-->	??	

简单的理解:就是浮点运算时会进行舍入, (-1e20 + 3.14)导致3.14丢失。

代码

Great Reality #1

  • Example 1: Is x2 ≥ 0?
#include <stdio.h>void reality(int a) {printf("%d*%d=%d\n",a, a, a*a);
}int main() {reality(40000);reality(50000);
}// output:
// 40000*40000= 1600000000
// 50000*50000=-1794967296

2^31 = 2147483648
50000*50000 = 2500000000
超出int32的边界了。

  • Example 2: Is (x + y) + z = x + (y + z)?
#include <stdio.h>void floatAdd(float a) {printf("(%f-%f)+3.14=%f\n",a,a, (a-a)+3.14);printf("%f+(-%f+3.14)=%f\n",a,a, a + (-a+3.14));
}int main() {floatAdd(1e20);
}// output:
// (100000002004087730000.000000-100000002004087730000.000000)+3.14=3.140000
// 100000002004087730000.000000+(-100000002004087730000.000000+3.14)=0.000000
  • Memory Referencing Bug
typedef struct {int a[2];double d;
}struct_t;double memoryRefBug(int i) {volatile struct_t s;s.d = 3.14;s.a[i] = 1073741824;printf("%d -> %lf\n",i,s.d);return s.d;
}
int main() {memoryRefBug(0);memoryRefBug(1);memoryRefBug(2);memoryRefBug(3);memoryRefBug(4);memoryRefBug(5);memoryRefBug(6);memoryRefBug(7);
}// output:
// 0 -> 3.140000
// 1 -> 3.140000
// 2 -> 3.140000
// 3 -> 2.000001
// 4 -> 3.140000
// 5 -> 3.140000
// 6 -> 3.140000

结构体和数组类似,元素的存储是紧挨着的。a[1] | a[2] | d
通过a[i]取,a[2]开始,就是引用的d中的值了进行操作了。

  • Memory System Performance Example
#include <stdio.h>
#include <windows.h>void copyij(int src[2048][2048], int dst[2048][2048]) {int i,j;for (i = 0;i < 2048;i++)for (j = 0;j < 2048;j++)dst[i][j] = src[i][j];
}void copyji(int src[2048][2048], int dst[2048][2048]) {int i,j;for (j = 0;j < 2048;j++)for (i = 0;i < 2048;i++)dst[i][j] = src[i][j];
}int main() {int src[2048][2048],dst[2048][2048];int i,j;for (j = 0;j < 2048;j++)for (i = 0;i < 2048;i++)src[i][j] = i;int start,end1,end2;start = GetTickCount();copyij(src,dst);end1 = GetTickCount();copyji(src,dst);end2 = GetTickCount();printf("copyij: %d, copyji:%d", end1 - start, end2 - end1);
}// output:
// copyij: 0, copyji:0

结果分析:
教材显示copyij() 的性能远远好于 copyji()。
为什么我运行的没有这个问题。难道是这个已经修复了?

问题:
在windows下报错:“Process finished with exit code -1073741571 (0xC00000FD)”
致的原因是StackOverflow(栈区溢出)
将数组设置为500长度就没事了。

linux 代码:

#include <stdio.h>
#include <math.h>
#include <time.h>int main() {int src[2048][2048],dst[2048][2048];int i,j;for (j = 0;j < 2048;j++)for (i = 0;i < 2048;i++)src[i][j] = i;clock_t start,end1,end2;start = clock();copyij(src,dst);end1 = clock();copyji(src,dst);end2 = clock();printf("copyij: %d, copyji:%d", ((double )(end1 - start))/CLOCKS_PER_SEC, ((double )(end2 - end1))/CLOCKS_PER_SEC);
}

报错:”Segmentation fault“

分析:
Segmentation fault就是指访问的内存超出了系统所给这个程序的内存空间。一般是随意使用野指针或者数组、数组越界。

处理方案:
将数组设置为500长度。

结果:

copyij: 0, copyji:3668

二维数组行遍历效率远高于列遍历效率

  • c语言遍历
    对c语言而言,数组在内存中是按行储存的,按行遍历时可以由指向数组第一个数的指针一直往下走,就可以遍历完整个数组,而按列遍历则要获得指向每一列的第一行的元素的指针,然后每次将指针指下一行,

  • CPU高速缓存
    缓存从内存中抓取一般都是整个数据块,所以它的物理内存是连续的,几乎都是同行不同列的,而如果内循环以列的方式进行遍历的话,将会使整个缓存块无法被利用,而不得不从内存中读取数据,而从内存读取速度是远远小于从缓存中读取数据的。

  • 分页调度
    物理内存是以页的方式进行划分的,当一个二维数组很大是如 int[128][1024],假设一页的内存为4096个字节,而每一行正好占据内存的一页,如果以列的形式进行遍历,就会发生128*1024次的页面调度,而如果以行遍历则只有128次页面调度,而页面调度是有时间消耗的,因而调度次数越多,遍历的时间就越长。

  • 局部性原理: CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。

三种不同类型的局部性:时间局部性,空间局部性,顺序局部性。

文档

二维数组按行和按列遍历效率哪个高?


http://www.ppmy.cn/news/1194869.html

相关文章

Dual Personalization on Federated Recommendation

联合推荐的双重个性化 代码链接 论文链接 主要创新 文章的主要创新是提出了一种双重个性化机制&#xff0c;用于增强联邦推荐系统的性能。这种机制能够在联邦学习框架中为每个本地模型学习用户特定的物品嵌入&#xff0c;从而显著提升推荐系统的效果。通过在四个数据集上进行…

Maxwell for 3dMax渲染器的安装方法

Maxwell渲染器的安装方法 Maxwell Render是一个基于控制光传输的数学方程的渲染引擎&#xff0c;这意味着所有元素&#xff0c;如发射器材料和相机&#xff0c;都是从物理精确的模型中导出的。Maxwell Render是无偏的&#xff0c;因此不使用任何技巧来计算场景中每个像素的照明…

pnpm 包管理器

通过npm 安装 pnpm npm install -g pnpm

Selenium 基本功能

#driver.quit()from selenium import webdriver from selenium.webdriver.chrome.service import Service# 尝试传参 s Service("chromedriver.exe") driver webdriver.Chrome(services)driver.get(https://www.baidu.com/) input()#1/导入Selenium库 from seleniu…

tuple 简易实现(C++ 模板元编程)

std::tuple 在标准库里面&#xff0c;tuple主要有下面四个类模板 or 函数模板 tupletuple_sizetuple_elementget 在后续有实现&#xff1a;tuple_size_v tuple_size::value和tuple_element_t tuple_element::type。 事例Example&#xff1a; auto tup std::tuple<in…

深入理解强化学习——强化学习的历史:时序差分学习

分类目录&#xff1a;《深入理解强化学习》总目录 相关文章&#xff1a; 强化学习的历史&#xff1a;最优控制 强化学习的历史&#xff1a;试错学习 强化学习的历史&#xff1a;试错学习的发展 强化学习的历史&#xff1a;K臂赌博机、统计学习理论和自适应系统 强化学习的…

java基础+数据库基础+系统+JVM问题

的哎的哎 1、基础部分 java线程池 队列的选择 答&#xff1a; SingleThreadPool:适用于多个任务顺序执行的场景。 它使用的是LinkedBlockingQueue<>()&#xff0c;无界的阻塞队列&#xff0c;就意味着会有内存溢出的风险。 FixedThreadPool: 适用于任务量固定耗时长的…

matlab双目标定中基线物理长度获取

在MATLAB进行双目摄像机标定时,通常会获得相机的内参,其中包括像素单位的焦距(focal length)以及物理单位的基线长度(baseline)。对于应用中的深度估计和测量,基线长度的物理单位非常重要,因为它直接影响到深度信息的准确性。有时候,您可能只能获取像素单位的焦距和棋…