低延迟代码设计涉及仔细的“注意您运行的系统”类型的编码和部署。这意味着,例如,标准IPC 机制(例如,使用 SysV msgsnd
/msgget
在进程之间传递消息,或pthread_cond_wait
/pthread_cond_signal
在 PThreads 端)以及普通锁定原语(自适应互斥体)将被视为相当慢......因为它们涉及需要数千个 CPU 周期的东西……即上下文切换。
相反,使用“热-热”切换机制,例如破坏者模式——生产者和消费者都在紧密的循环中旋转,永久轮询单个或最坏情况下少数原子更新的内存位置,这些位置说明下一个项目的位置-be-processed 被发现和/或标记已处理的项目完成。将所有生产者/消费者绑定到单独的 CPU 内核,以便它们永远不会进行上下文切换。
在这种类型的用例中,无论您是使用单独的线程(并通过共享相同地址空间的所有线程隐式获得内存共享)还是单独的进程(并通过使用共享内存来显式地获得内存共享) -processed 以及队列 mgmt “元数据”)几乎没有什么区别,因为 TLB 和数据缓存“总是很热”(您永远不会进行上下文切换)。
如果您的“处理器”不稳定和/或没有保证完成时间,则无论如何都需要添加“收割机”机制来处理失败/超时消息,但这种垃圾收集机制必然会引入抖动(延迟峰值)。那是因为你需要一个系统调用来确定一个特定的线程或进程是否已经退出,即使在最好的情况下,系统调用延迟也只有几微秒。
从我的角度来看,您正在尝试在这里混合油和水;您需要使用未专门为低延迟部署/不受您控制的库代码而编写的库代码,以及使用纳秒延迟进行消息调度的要求。没有办法让例如pthread_cond_signal()
给你 nsec 延迟,因为它必须执行系统调用来唤醒目标,这需要更长的时间。
如果你的“处理程序代码”依赖于“丰富”的环境,并且在这些和主程序之间共享了大量的“状态”......这听起来有点像在说“我需要让蒸汽驱动的飞机休息”音障”……