MaLing 离开某厂纪念文 & 介绍 aliworkqueue
这个签名如果各位认识的话: "减少状态的改变是优化性能的关键,状态的改变恰恰是熵增的过程" 本文主要介绍 aliworkqueue(Adaptive Lock Integration, 缩写是不是巧合留给各位思考). 初版提交时 [1] 叫做 adv_spinlock, 后改名 alispinlock. 这个辅助函数在最终版 [3] 中被拿掉了 (替换 spinlock -> workqueue 应该就能用了), 难说这个东西是否应该 inline. static void ali_spin_lock(struct ali_spinlock *lock, void (*fn)(void *), void *para) { struct ali_spinlock_info info __attribute__((aligned(64))); info.flags = 0; info.fn = fn; info.para = para; alispinlock(lock, &info); }
2018.12 MaLing 把改版的 NUMA spinlock 提交给 glibc. 用法基本一致不提. 独立使用版 https://gitlab.com/numa-spinlock/numa-spinlock --- MaLing 本人的解说 [1][2]: Spinlock caused cache line ping-pong between cores, we have to spend lots of time to get serialized execution. However if we present the serialized work to one core, it will help us save much time. pinlock的目的就是让大家串行花完成工作 因此如果将所有的工作让一个CPU完成,就可以达到我们的目的 这就是优化的原理(也可以说减少状态的改变)。 queued spinlock 本身减少了CPU core之间争抢lock cache line 因此将所有的core的请求挂成一条链, 我们继承了他的想法,将函数地址和参数也挂上去 这样锁的拥有者顺着链路执行所有函数, 减少了共享区的缓存乒乓(提升了2倍),当然也减少了锁的争抢 这也是我为什么说在两个线程时候性能提升超过3倍! 现在是等待本地缓存变量被置0,然后等待锁的拥有者置1,这样就代表获得锁。 在我们的实现机制中也代表临界区代码执行完毕,可以继续运行了。 --- 换偶解释的话, 偶会认为抢同一把锁的 fn 一般只有一两种, 抢锁的时候 fn 的内容, fn 访问过的 global variable 各自还在 L1i/L1d Cache 里, 所以已经拿到锁的 CPU core 继续执行到结束就可以了. 使用方法应该是这样的: 1 把 spinlock_t 替换成 ali_workqueue_t 并替换初始化方法为 ali_workqueue_init. 2 把 spin_lock ... spin_unlock 之间的临界区操作做成类似 callback 的 fn. (只能传一个指针. 可能需要加 struct. 需要返回值的也要预留) 3 调用上面的辅助函数 ali_spin_lock(*lock, fn, *arg) (inline 的效果和嵌到代码里应当差不多, 自由选择) 需要注意的是替换 spin_lock_irq 系列时需要在 fn 的前头写 local_irq_save 并最终 local_irq_restore. 同理 spin_lock_bh 是 local_bh_disable / local_bh_enable 对. 可以参考 slab (list_lock) 的修改例子 [4]. 用 kernel 的 lockstat 机制可以发现潜在的 contention [5], 需要 CONFIG_LOCK_STAT. 输出也会包括其他各种类型的锁. echo 1 >/proc/sys/kernel/lock_stat (run your program) echo 0 >/proc/sys/kernel/lock_stat 然后 less /proc/lock_stat 即可. perf lock 应该是这组命令的封装, contended 数值明显的锁就可以用这种方法变换一下. LWN 关于 qspinlock 的文章 [6] 说有 ext4 文件系统相关的测试提升了 116%, VFS 和 ext4 里锁争用都很严重所以有效果. 而 MaLing 先改了 slab 背后应当也是有数据支撑的. --- 题目的另外一半是 MaLing 离开 A 厂. "正式加入高频交易" http://www.newsmth.net/nForum/article/ProgramTrading/128183 换 ARM 处理器的问题这个回复也比较意外, 直接贴上, 这个很难评论. http://www.newsmth.net/nForum/article/CSArch/49360 发信人: MaLing (uranus), 信区: CSArch 标题: Re: 阿里将大量采用ARM处理器代替Intel 发信站: 水木社区 (Sun Dec 11 15:39:58 2016), 站内 移植验证工作就是我们两年的工作,除了大量矩阵计算x86优秀, 其他方面arm更好,尤其华为,Cavium,高通的在我离开前出了24核心。 arm的多小核特性与我们的应用体系吻合的很好,小缓存(LLC)也不是问题。 --- [1] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1012696.html [2] http://www.newsmth.net/nForum/article/CSArch/45019 [3] https://lkml.org/lkml/2016/4/15/2 [4] http://lkml.iu.edu/hypermail/linux/kernel/1602.0/03745.html [5] https://www.kernel.org/doc/Documentation/locking/lockstat.txt [6] https://lwn.net/Articles/590243/ --- ps: 思考题. 如果有 n 个进程用 spinlock 的方式同时抢锁, 每个进程有 m 个任务, 抢到锁得到许可的瞬间就认为能完成工作 (即抢锁的粒度就是 1 时间片, 这个时间片能完成 1 个任务). 但总线当且仅当只有一个进程申请锁时才发放许可的话, 所有任务期望的结束时间最短可以是多少? (hint: 抢不过应当休息多长时间? 总是占着不走的话谁也抢不到) (hint2: 除了抢锁, 还可以选择在旁观察. 但选择了观察, 那本周期不能参与)