NUMA架构下无锁链表队列的线程亲和性优化问询
问题背景
我正在实现多种无锁队列数据结构,测试环境分为两类:
- 64核(128线程)的NUMA架构机器,用于性能测试
- 本地4核(8线程)机器,用于调试测试
队列采用链表结构,每个节点是一段连续数组形式的Segment,供生产者和消费者共同访问。当出现线程饥饿或当前Segment已满时,需要关闭并丢弃该Segment(此操作容易引发活锁),同时分配新的Segment并链接到队列中。
队列固定长度限制的两种实现方案
我测试了两种实现队列固定长度限制的方案:
- 方案1:依赖全局原子计数器,入队操作递增计数器、出队操作递减计数器;每次操作都要加载计数器判断是否符合长度限制,不符合则操作失败
- 方案2:依赖全局Segment计数器,新增Segment时递增计数器、释放旧Segment时递减计数器;仅在新增Segment时判断计数器是否超出固定值
测试结果差异
- 本地调试测试:两种方案性能差异显著,符合预期——方案1几乎每次操作都要修改全局计数器,会引发更多缓存失效问题,性能明显低于方案2
- NUMA机器性能测试:两种方案的性能差异极小,且整体性能远低于本地同参数测试结果(已确认超线程开启与否不会影响机器负载)
瓶颈分析与疑问
我认为性能瓶颈在于对共享队列的跨NUMA集群访问,因此想询问是否存在标准算法来设置线程亲和性,从而减少跨集群访问带来的开销。
我曾在一篇论文中看到一种部分解决方案:为队列添加一个代表主要操作集群的字段,线程操作队列时先检查该字段与自身所在集群是否一致,若不一致则等待并通过CAS更新该字段。但我认为如果不主动控制线程亲和性,这个方案的优化效果会非常有限。
需求目标
我主要寻求一种公平的实现方式,能够适配以下场景:
- 平衡多对多(生产者与消费者数量相当)
- 非平衡(生产者与消费者数量差距较大)
- 一对多(单个生产者对应多个消费者,或单个消费者对应多个生产者)
内容的提问来源于stack exchange,提问作者Mattia Piras
相关产品推荐
相关产品推荐

