Read-Copy-Update

Read-Copy-Update

2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

自旋的后果

同一份计算任务,时间 (CPU cycles) 和空间 (内存占用) 会随处理器数量的增长而变化。

center

用自旋锁实现 sum++:更多的处理器,更差的性能
2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

Scalability: 性能的新维度

严谨的统计很难

  • CPU 动态功耗
  • 系统中的其他进程
  • 超线程
  • NUMA
  • ……

Benchmarking crimes by Gernot Heiser

2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

自旋锁的使用场景

操作系统内核的并发数据结构 (短临界区)

  • 临界区几乎不 “拥堵”,迅速结束

Kernel 里有 ~180K 个并发控制函数调用!

2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

观察

许多操作系统内核对象具有 “read-mostly” 特点

例子

  • 路由表
    • 每个数据包都要读
    • 网络拓扑改变时才变更
  • 用户和组信息
    • 无时不刻在检查 (Permission Denied)
    • 但几乎从不修改用户
2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

一个非常聪明的想法:Read-copy-update

Counter *c_current;

int get() {
    // Read
    Counter *c = c_current;
    return c->sum;
}

void increment() {
    SPIN_LOCKED {
        // Copy
        Counter *c = alloc_counter();
        c->sum = c_current->sum + 1;
        smp_wmb(); // Memory barrier

        // Update
        c_current = c;
    }
}
2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

讨论

改写 = 复制

  • 任何对象都可以复制!
    • (甚至可以只复制改变的部分)
    • 例子:链表
  • 允许某一时刻,不同 CPU “看到” 不同版本

何时回收旧版本?

  • 版本对象会存在一个 “graceful period”
  • 直到某个时刻,所有 CPU read 都会访问到新版本
    • 怎么准确地找到这个时间点?
2024 南京大学《操作系统:设计与实现》
Read-Copy-Update

Linux 内核的复杂性 (不建议新手碰的原因)

center

2024 南京大学《操作系统:设计与实现》