标签

#Atomics

6 篇

低延迟系统开发 #17 约 10 分钟

wait-free

wait-free 不是更快的 lock-free:它把 CAS 失败从“再来一次”变成“我排在你后面”,每个线程的步数因此有了上界,代价是更多原子操作和更难写对的代码。

低延迟系统开发 #16 约 25 分钟

自旋锁

自旋锁快不快,看等锁的核在干什么:每次都读改写,就把锁所在的行抢来抢去;先读后抢、循环里加 PAUSE、抢输了退一步,等的时候才几乎不打扰持锁的核。

低延迟系统开发 专题 约 10 分钟

MESI 缓存一致性

MESI 只执行一条规矩:一条缓存行,要么只有一个核能写,要么有任意多个核只能读,两者不会同时存在。四个状态就是两个问题的答案——别人有没有这一行?我改过没有?协议里的每一笔代价,不是在层与层之间搬数据,就是在等另一个核确认。伪共享、SPSC 队列的缓存游标、读者越多生产者越慢,都是同一台状态机。一致性仍然不保证多字读取不撕裂,也不管不同地址的写谁先谁后,那是内存屏障的事。

低延迟系统开发 #5 约 16 分钟

共享内存里的 SPMC 广播环

行情只有一个生产者,却有好几个消费者,每个都要看到每一条,而生产者是热路径,不能等任何人。答案是广播环:每个槽位自带序号戳,读者各持私有游标,生产者写满一圈就覆盖最老的槽位,从不读读者的状态。代价转给了读者:套圈是无声的;读完再复查一次戳,只有在写者先作废戳的前提下才抓得到写了一半的槽位;追上来的读者会抢走生产者要写的那一行,全速写时每条都变贵。放进共享内存再加三条:元素里不能有任何指针,第一圈每 32 条碰一次缺页,读者重启不存游标就全丢。

低延迟系统开发 #4 约 15 分钟

无锁队列与 Micro-Batching

无锁 SPSC 队列成立,是因为每个共享变量只有一个写者:每一边只写自己的下标,只读对方的。剩下的工作是别让这个性质被悄悄破坏:元素个数用两个下标相减而不是共享计数器,对方的下标缓存一份、只在看起来满了或空了时才刷新,日志按文本段推而不是按字符推。SPSC 只在“失败就返回”的接口下才是 wait-free,有界队列满了总得在丢弃和阻塞之间选一个。

低延迟系统开发 #2 约 12 分钟

内存序与缓存行

同一套缓存硬件带出两个不相干的问题。正确性:写先进 store buffer,别的核要过一段时间才看得见,靠 release/acquire 配对补上顺序。性能:就算每个值都读对了,两个核抢同一条缓存行(伪共享)照样慢,靠缓存行布局解决。