1、冯诺依曼模型
运算器、控制器、存储器、输入设备、输出设备
32位和64位CPU最主要区别是一次性能计算多少字节数据,如果计算的数额不超过 32 位数字的情况下,32 位和 64 位 CPU 之间没什么区别的,只有当计算超过 32 位数字的情况下,64 位的优势才能体现出来。
线路位宽 cpu能操作的内存大小 比如cpu想要操作4G的内存,就需要32条地址总线。2^32=4G
2、程序执行的基本过程
一个程序执行的时候,CPU 会根据程序计数器里的内存地址,从内存里面把需要执行的指令读取到指令寄存器里面执行,然后根据指令长度自增,开始顺序读取下一条指令。
3、指令的执行速度
程序的CPU执行时间=指令数*每条指令的平均时钟周期数*时钟周期时间
时钟周期时间=1/电脑主频 如1/2.4G
4、存储
寄存器
CPU cache SRAM 静态随机存储器
- 每个 CPU 核心都有一块属于自己的 L1 高速缓存,指令和数据在 L1 是分开存放的,所以 L1 高速缓存通常分成指令缓存和数据缓存。
- L2 高速缓存位置比 L1 高速缓存距离 CPU 核心 更远 大小比 L1 高速缓存更大
- L3 高速缓存通常是多个 CPU 核心共用的
内存 DRAM (Dynamic Random Access Memory,动态随机存取存储器) 的芯片。数据会被存储在电容里,电容会不断漏电,所以需要「定时刷新」电容,才能保证数据不会被丢失
CPU 从 L1 Cache 读取数据的速度,相比从内存读取的速度,会快 100
多倍
硬盘
- 固态硬盘:断电后数据还是存在的,而内存、寄存器、高速缓存断电后数据都会丢失。内存的读写速度比 SSD 大概快
10~1000
倍。 - 机械硬盘:通过物理读写的方式来访问数据的,因此它访问速度是非常慢的,它的速度比内存慢
10W
倍左右。
每个存储器只和相邻的一层存储器设备打交道
5、如何写出让CPU 跑的快的代码
CPU Cache 的数据是从内存中读取过来的,它是以一小块一小块读取数据的
CPU L1 Cache 分为数据缓存和指令缓存,因而需要分别提高它们的缓存命中率:
- 对于数据缓存,我们在遍历数据的时候,应该按照内存布局的顺序操作,这是因为 CPU Cache 是根据 CPU Cache Line 批量操作数据的,所以顺序地操作连续内存数据时,性能能得到有效的提升;
- 对于指令缓存,有规律的条件分支语句能够让 CPU 的分支预测器发挥作用,进一步提高执行的效率;
对于多核 CPU 系统,线程可能在不同 CPU 核心来回切换,这样各个核心的缓存命中率就会受到影响,于是要想提高线程的缓存命中率,可以考虑把线程绑定 CPU 到某一个 CPU 核心。
6、cpu缓存一致性
写数据
写直达 如果cache已经存在,则更新后写入内存 如果cache不存在,则把数据更新到内存
写回 对于已经缓存在 Cache 的数据的写入,只需要更新其数据就可以,不用写入到内存,只有在需要把缓存里面的脏数据交换出去的时候,才把数据同步到内存里,这种方式在缓存命中率高的情况,性能会更好
如何缓存一致
- 写传播,也就是当某个 CPU 核心发生写入操作时,需要把该事件广播通知给其他核心;
- 第二点是事物的串行化,顺序
总线嗅探机制的 MESI 协议 已修改、独占、共享、已失效
对于在「已修改」或者「独占」状态的 Cache Line,修改更新其数据不需要发送广播给其他 CPU 核心。
7、伪共享
CPU Cache Line 大小一般是 64 个字节 这种因为多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象称为伪共享
如何避免?
多个线程共享的热点数据,即经常会修改的数据,应该避免这些数据刚好在同一个 Cache Line 中,否则就会出现为伪共享的问题。
在 Linux 内核中存在 __cacheline_aligned_in_smp
宏定义,是用于解决伪共享的问题。是用空间换时间
字节填充
8、cpu选择线程
- SCHED_DEADLINE:是按照 deadline 进行调度的,距离当前时间点最近的 deadline 的任务会被优先调度;实时任务总是会比普通任务优先被执行
- SCHED_FIFO:对于相同优先级的任务,按先来先服务的原则,但是优先级更高的任务,可以抢占低优先级的任务,也就是优先级高的可以「插队」;
- SCHED_RR:对于相同优先级的任务,轮流着运行,每个任务都有一定的时间片,当用完时间片的任务会被放到队列尾部,以保证相同优先级任务的公平性,但是高优先级的任务依然可以抢占低优先级的任务;
9、软中断
中断处理程序的上部分和下半部可以理解为:
- 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行;
- 下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行;
Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型 软中断的处理是通过“ksoftirqd”内核线程来实现的
10、补码
有了补码,负数的加减法操作,实际上是和正数加减法操作一样的
十进制整数转二进制使用的是「除 2 取余法」,倒序
十进制小数使用的是「乘 2 取整法」正序
计算机存小数 符号位 指数位 尾数位
小数计算不精确的原因
因为有的小数无法可以用「完整」的二进制来表示,所以计算机里只能采用近似数的方式来保存,那两个近似数相加,得到的必然也是一个近似数。