JYY永远的神!在我心目中和y总肩并肩的男人!
文章结构
- 梳理内容
- ppt总结
所有程序都是状态机,这个我学过nand2已经理解较深了。
并发编程,我以前一直以为并发编程是在一个处理器上,那设一个共享变量不就完事儿了吗。实际上现在电脑基本都是多处理器了,带来了以下三个问题。
-
多处理器的出现意味着“原子性”的丧失
“程序 (甚至是一条指令) 独占处理器执行” 的基本假设在现代多处理器系统上不再成立。 -
编译器的不断进化导致“顺序性”的丧失
编译器对内存访问 “eventually consistent” 的处理导致共享内存作为线程同步工具的失效 -
CPU(处理器)的不断进化导致“可见性”的丧失,满足单处理器 eventual memory consistency 的执行,在多处理器上可能无法序列化!
可见性就是说你认为无论怎样都不可发生的情况发生了
原因在于:现在的处理器也有“编译功能”,把一条指令拆成更小的模块优化。
那么怎么样才能夺回原子性,顺序性,可见性?
原子性:上锁
顺序性:memory 熟悉编译器
可见性:nfence 使用好cpu的内存模型
ps:还没写完,27号写完
Q:到底什么是 “程序”?
Take-away message
程序 = 状态机
源代码S: 状态迁移 = 执行语句
二进制代码C: 状态迁移 = 执行指令
编译器 C=compile(S)
应用视角的操作系统就是一条 syscall 指令
计算机系统不存在玄学;一切都建立在确定的机制上
理解操作系统的重要工具:gcc, binutils, gdb, strace
Q: 如何理解多处理器系统?
Take-away message
多处理器编程:入门
多处理器程序 = 状态机 (共享内存;非确定选择线程执行)
thread.h = create + join
多处理器编程:放弃你对 “程序” 的旧理解
不原子、能乱序、不立即可见
来自于编译优化 (处理器也是编译器
Q: 如何理解各种并发程序?
Take-away message
并发程序 = 状态机
线程共享内存
每一步非确定选择线程执行
画状态机就对了
当然,用工具帮你画 (model checker)
Q: 如何在多处理器系统上实现互斥?
Take-away message
软件不够,硬件来凑 (自旋锁)
用户不够,内核来凑 (互斥锁)
找到你依赖的假设,并大胆地打破它
Fast/slow paths: 性能优化的重要途径
Q: 如何在多处理器上协同多个线程完成任务?
Take-away message
实现同步的方法
条件变量、信号量;生产者-消费者问题
Job queue 可以实现几乎任何并行算法
不要 “自作聪明” 设计算法,小心求证