缓存一致性

  • 缓存和内存的一致性,两种不同的策略
    • 写直达:只要需要写,就直接写到内存,这样写的次数比较多
    • 写回 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 的缓存失效。

调度器

  • 每个任务有一定优先级,099 之间是实时任务,100139 之间是普通任务;
  • Deadline 调度类
  • Realtime 调度类,有 FIFO 和 Round Robin 两种调度策略
  • Fair 调度类(用于普通任务),通过完全公平调度器 CFS 实现(红黑树),有 NORMAL 和 BATCH(低优先级)两种策略。虽然叫完全公平,但是还需要考虑优先级
  • 通过 nice 值人为干预进程的优先级

中断

  • 硬中断:由硬件触发(例如,键盘中断),因为中断处理程序可能会暂时关闭中断,所以需要快速处理,否则可能导致丢失中断
  • 软中断:由内核触发,用来处理硬中断没处理完的东西