Linux 具有非常低唤醒延迟的锁
我正在编写一个读写器队列,它需要尽可能低的延迟。writer的频率不足以让读卡器一直处于繁忙状态,所以在常见的实现中,如果队列为空,读卡器就会等待锁并进入睡眠状态。当一些东西被放入队列时,读取器被唤醒,但是,这会导致上下文切换并引入延迟。另一种方法是使用自旋锁,但它使用原子操作,原子操作本质上锁定总线,从而在总线上造成大量负载,影响其他作业的性能 我的问题是,有没有一种方法可以让读卡器处于空闲状态,而不产生CPU,但同时又不会给总线带来沉重的负载,并且无论什么时候,它都可以退出空闲状态并立即继续。目标是尽可能降低从放入队列的内容到读取器开始处理它的延迟。我可以为读卡器线程分配一个专用的CPU内核,所以读卡器空闲时CPU浪费不是问题Linux 具有非常低唤醒延迟的锁,linux,multithreading,linux-kernel,Linux,Multithreading,Linux Kernel,我正在编写一个读写器队列,它需要尽可能低的延迟。writer的频率不足以让读卡器一直处于繁忙状态,所以在常见的实现中,如果队列为空,读卡器就会等待锁并进入睡眠状态。当一些东西被放入队列时,读取器被唤醒,但是,这会导致上下文切换并引入延迟。另一种方法是使用自旋锁,但它使用原子操作,原子操作本质上锁定总线,从而在总线上造成大量负载,影响其他作业的性能 我的问题是,有没有一种方法可以让读卡器处于空闲状态,而不产生CPU,但同时又不会给总线带来沉重的负载,并且无论什么时候,它都可以退出空闲状态并立即继续
有什么想法吗?如果您关心的是延迟,只需不锁定地旋转即可。确保在变量中使用关键字“volatile”
它在总线负载或内存绑定方面不会有任何缺点,因为实际上您正在检查L1/L2/。。。隐藏物缓存在内核之间自动同步。您可以旋转,也可以阻塞,两者之间没有任何内容
sys_futex
将是最轻量级的东西,如果你想阻止(但也是最不可移植的)。大多数情况下,人们希望在大多数情况下都不旋转或阻塞(但使用原子操作对队列进行无锁修改),并且在出现某些“特殊”情况(如队列已满或队列已空)时,不旋转或阻塞。@Damon,它不必是可移植的。看起来sys_futex仍然有一个等待队列,等待时会产生CPU,不是吗?基本上,我想要的是,在等待时,线程不会放弃CPU,而是运行一些循环,运行空闲指令,不会将负载放到总线上。每当有东西放入队列时,writer都会以某种方式向读线程发出信号,使其退出循环。您必须在多核系统上运行,并且必须找到一种方法将读线程绑定到一个内核,该内核禁用了上下文切换,这样它就可以在不发生上下文切换的情况下休眠。如果没有一些内核级的黑客攻击,您可能无法做到这一点。@icando:在循环中运行空闲指令是在旋转,这是没有好处的。在无事可做时放弃CPU是正确的sys_futex
确实做到了这一点,开销尽可能低。您可以做的是实现一个协同程序系统(使用宏破解或使用setjmp
/longjmp
,也有现成的C库可以做到这一点)。所有的协程实现或多或少都是丑陋的黑客行为,但是如果你不想放弃CPU,那么运行一个协程有一个优势,那就是你可以在同时做有用的事情,而不是旋转。@Damon,正如我所说,我想优化的是延迟,所以在不做任何事情的情况下浪费CPU是可以的。即使使用sys_futex,当您将线程置于睡眠状态并将其唤醒时,上下文切换和进出内核空间仍然存在开销,这是我想要避免的开销。至于协同路由,当协同路由运行时,读卡器不能立即运行,而是等待协同路由放弃CPU,这是完全不可接受的。