我对缓存一致性开销有疑问。我想设计一个响应速度非常快的通信隧道。这是在内存中与不同cpu中的两个线程/进程通信。它是一对一或广播通信,这意味着它只有一个作家,但可能有一个或多个读者。他们使用共享内存。隧道可能是一个圆形缓冲区,其整数作为其在头部的写入位置。假设编写者和每个读者都在不同的CPU中,并且都是没有上下文切换的实时系统。
一种方法是,每个读者保持自己的阅读位置,然后旋转并循环以检查缓冲区中作者位置的位置。一旦他们发现两个整数不同,这意味着readReady和读者可以读取一个元素并将其读取位置移到一个元素前面。这是读取修改写入条件,但由于它是非常原子的基本类型(如整数或字节),只有一次写入,并且假设内存对齐也是常规的,这应该是安全和快速的。唯一的问题是当编写器将值写入缓存时(假设intel缓存被写回),修改不会立即传播到其他缓存,并且读取器读取自己的缓存并认为值未更改。硬件会自动缓存一致性,所以读者可以很快得到修改,但这会带来一些开销。
我知道最传统的实现方法是使用信号或条件变量让读者等待作者的通知。我担心这些方法可能有系统调用并带来数百个周期开销,或者使线程睡眠等待并带来更大的延迟。我不是这个问题的专家。如果我们唯一关心的是延迟,我想知道哪种方式更好?还是有更好的方法吗?谢谢
答案 0 :(得分:1)
如果您的关注只是延迟,那么忙碌等待将为您提供更低的延迟。不幸的是,它还会为您带来更高的功耗和更高的CPU使用率。
对于某些应用程序,高CPU使用率不是问题,但如果用户使用笔记本电脑或手机型设备,这是一个非常糟糕的解决方案,因为它会吃掉电池(如果是某些设备) ,因为你已经设法加热CPU足以使热管理开始降低设备的速度,因此减慢了速度。即使在插入的服务器上,功耗也不容忽视 - 服务器机房中的CPU产生的热量必须通过空调提取 - 至于运行成本,AC的成本通常与成本相同。运行服务器本身。因此,如果您编写一个优于其他人的优秀应用程序,但通过忙碌等待使用更多功能,那么与同一市场中的竞争产品相比,它可能会使您处于劣势。
它对系统中其他应用程序的性能也有害。如果你有一个具有足够内核的专用系统来应对你的应用程序以及它需要的任何其他内容,那么这也不是问题。如果它在通用机器上运行将是一个问题。
当然,这也取决于你是否希望一个线程不断发送消息,或者它是否一次又一次地闲置。
一个简单的系统调用的实际长度大约是100-1000秒的周期(取决于OS版本,什么处理器等),如果操作系统决定运行其他东西,它很可能最终成为一个更大的数字。