与linux信号/条件变量相比,缓存一致性开销

cache coherence overhead compared with linux signal / conditional variable

本文关键字:缓存 一致性 开销 变量 linux 信号 条件      更新时间:2023-10-16

我有一个关于缓存一致性开销的问题。我想设计一个响应速度非常快的通信隧道。这是在内存中与不同cpu中的两个线程/进程进行通信。它是一对一或广播通信,这意味着它只有一个作者,但可能有一个或多个读者。他们使用共享内存。隧道可能是一个圆形缓冲区,其在头部的写入位置为整数。假设编写器和每个读取器都在不同的CPU中,并且都是实时系统,没有上下文切换。

一种方法是,每个读取器都保持自己的读取位置,并旋转和循环以检查其在缓冲区中的位置和写入器位置。一旦他们发现两个整数不同,这意味着readReady和reader可以读取一个元素,并将读取位置向前移动一个元素。这是读取-修改-写入条件,但由于它是非常原子的基本类型(如整数或字节),只有一次写入,并且假设内存对齐也是规则的,所以这应该是安全和快速的。唯一的问题是,当写入程序将值写入缓存时(假设intel缓存是回写的),修改不会立即扩散到其他缓存,而读取器读取自己的缓存并认为值没有更改。硬件会自动进行缓存一致性,这样读者就可以很快得到修改,但这会带来一些开销。

我知道实现这一点的最传统的方法是使用信号或条件变量让读取器等待写入器的通知。我担心这些方法可能会有系统调用并带来数百个周期的开销,或者使线程睡眠等待并带来更大的滞后。我不是这个问题的专家。我想知道,如果我们唯一关心的是延迟,哪种方式更好?或者有更好的方法吗?感谢

如果您关心的只是延迟,那么繁忙的等待会给您带来更低的延迟。不幸的是,它还会给你带来更高的功耗和更高的CPU使用率。

对于某些应用程序来说,高CPU使用率不是问题,但如果用户有笔记本电脑或手机类型的设备,这是一个非常糟糕的解决方案,因为它会消耗电池(对于某些设备,速度会减慢,因为你已经设法将CPU加热到足够的温度,从而启动热管理来降低设备的速度)。即使在插入电源的服务器上,功耗也不容忽视——服务器机房中CPU产生的热量必须通过空调提取——至于运行成本,空调的成本通常与服务器本身的运行成本相同。因此,如果你写了一款优秀的应用程序,它比其他人的都好,但在繁忙的等待中消耗了更多的电量,那么与同一市场的竞争产品相比,它很可能会让你处于劣势。

这也不利于系统中其他应用程序的性能。同样,如果你有一个有足够核心的专用系统来处理你的应用程序和其他需要的东西,这不是问题。如果它在通用机器上运行,那就成了问题。

当然,这也取决于你是否期望一个线程不断地发送消息,或者它是否时不时地处于空闲状态。

一个简单系统调用的实际长度大约是100-1000秒的周期(取决于什么操作系统版本、什么处理器等),如果操作系统决定运行其他程序,它很可能会变成一个更大的数字。