注:本文为读书笔记,非原创
冯诺依曼模型
程序执行基本过程
注意: 数据和指令在内存中是分开存储的。指令存放区域又名 正文段.
上面这4个阶段,我们称作 指令周期。
程序的CPU执行时间 = CPU时间周期数 X 时钟周期时间
程序的CPU执行时间 = 指令数 X CPI X 时钟周期时间
64 位相⽐ 32 位 CPU 的优势在哪吗?64 位 CPU 的计算性能⼀定⽐ 32 位 CPU ⾼很多吗?
默认CPU位宽=线路位宽(地址总线/数据总线)
- 计算超过32位的数字时,64位CPU的优势才能体现出来;
- 64位CPU的最大寻址地址是2^64,远超过32位CPU。
你知道软件的 32 位和 64 位之间的区别吗?再来 32 位的操作系统可以运⾏在 64 位的电脑上吗?64 位的操作系统可以运⾏在 32 位的电脑上吗?如果不⾏,原因是什么?
64位和32位软件/操作系统,指的是其指令是64位还是32位;
- 因此,64位CPU可以兼容32位指令;64位指令则不能在32位CPU上执行,因为32位的寄存器存不下64位指令。
存储器
CPUCache的读操作
CPU怎么知道访问的内存数据是否在Cache中?最简单的办法:直接映射Cache。 (除直接映射外,还有全相连/组相连等)
这种方式下的内存地址:
当CPU访问一个内存地址后,会经历4个步骤:
- 得到CPUCache的索引
- 判断有效位,若为0则直接访问内存并加载至CPUCache;
- 对比组标记,若不一致则直接访问内存并加载至CPUCache;
- 根据偏移量,从CPU Line中读取对应的字. CPU从CPUCache中读取数据时,并不是读取整个CacheLine,而是读取所需要的一个数据片段,称为字.
如何写出让CPU跑得更快的代码?
CPU L1Cache分为数据缓存和指令缓存;因此:
- 对于数据缓存,遍历数据时,按照内存布局的顺序操作;
- 对于指令缓存,有规律的条件分支语句能够发挥CPU分支预测器的作用. 另外,对于多核CPU,线程可能在不同CPU核心来回切换,对各个CPU的缓存命中率造成影响;可以考虑把线程绑定在一个CPU上.
CPUCache的写操作
写直达
写回
缓存一致性问题
解决这一问题,要做到两点:
- 写传播: 某个CPU的Cache数据更新时,必须将该消息传播给其他CPU。
- 事物的串行化: 各CPU操作必须一致有序。 解决方案:MESI协议
对于M\E状态,修改数据不需要广播给其他CPU.
伪共享问题
当B线程需要修改变量B时:
解决办法:
在实际应用中可以通过 字节填充,大小字节对齐 的方式.
CPU如何选择线程
在linux内核中,进程和线程都是用 tark_struct 结构体表示的;线程的部分资源是共享了进程创建的资源,因此在linux中被称为轻量级进程.
所以,linux内核里的调度器,调用的对象就是 tark_struct.
- dl_rq: Deadline运行队列 ,优先调度离Deadline最近的任务;
- rt_rq: 实时任务运行队列 ,相同优先级,服从FIFO和时间片原则;但更高优先级任务可以抢占。
- csf_rq: CFS运行队列 ,优先选择vruntime少的任务,最左侧的叶子节点,就是下次会被调度的任务.
优先级:dl_rq > rt_rq > csf_rq
csf_rq中,每个任务初始vruntime相等.
调整优先级
调整任务的nice值.nice值调整的是普通任务的优先级.
CPU中断
为了避免中断处理程序执行过久,影响正常进程调度,linux将中断处理程序分为:
- 上半部:对应硬中断,由硬件触发,用来快速处理中断;
- 下半部:对应软中断,由内核触发,异步处理上半部未完成的工作;
硬中断: 打断CPU正在执行的任务,立即执行中断处理程序
软中断: 以内核线程方式执行,并且每个CPU都对应一个软中断内核线程; 当然,软中断不仅只是硬件设备中断处理程序的下半部,还包括一些内核自定义事件,如内核调度等.