
缓存一致性
- 缓存和内存的一致性,两种不同的策略
- 写直达:只要需要写,就直接写到内存,这样写的次数比较多
- 写回 Write Back:标记脏数据
- 缓存(之间的)一致性:L1/L2 缓存每个 CPU 核心独有,所以写缓存导致每个核心中的数据不一样
- 写传播:需要让别人知道你的修改
- 事务串行化:每个核心中修改的顺序都一样
- 总线嗅探:就是每个核心改完缓存之后都去通知其他的所有核心,但是比较麻烦,而且不保证事务串行化
- MESI 协议
- 保证事务串行化
- 分成 Modified/Exclusive/Share/Invalidated 四个状态,来回转化
伪共享
- 多个线程如果反复读写一些数据,这些数据映射到同一个 Cache Line 中,则会互相影响,导致缓存失效
__cacheline_aligned_in_smp
可以在有多个核心的情况下,让一个结构体的字段按 Cache Line 大小对齐,这样里面的两个字段一定位于不同的 Cache Line 中。用空间换时间。
- 伪共享问题解决的是完全不同的数据因为位于同一个 Cache Line 而导致的缓存失效,例如线程 A 读写 a 变量,线程 B 读写 b 变量。而不是线程 A 和 B 都读写 a 变量的这种情况。
- Java 的 Disruptor 库中有一个
RingBufferFields
类,里面是一些只读的元素。通过将它填充至 Cache Line 大小的整数倍,使得对任何其他内存的频繁读写都不会使得存放 RingBuffer
的缓存失效。
调度器
- 每个任务有一定优先级,0
99 之间是实时任务,100139 之间是普通任务;
- Deadline 调度类
- Realtime 调度类,有 FIFO 和 Round Robin 两种调度策略
- Fair 调度类(用于普通任务),通过完全公平调度器 CFS 实现(红黑树),有 NORMAL 和 BATCH(低优先级)两种策略。虽然叫完全公平,但是还需要考虑优先级
- 通过 nice 值人为干预进程的优先级
中断
- 硬中断:由硬件触发(例如,键盘中断),因为中断处理程序可能会暂时关闭中断,所以需要快速处理,否则可能导致丢失中断
- 软中断:由内核触发,用来处理硬中断没处理完的东西