c++ - 与 linux 信号/条件变量相比的缓存一致性开销

标签 c++ linux multithreading caching signals

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

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

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

最佳答案

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

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

这对系统中其他应用程序的性能也很不利。同样,如果您有一个具有足够核心的专用系统来处理您的应用程序以及它需要的任何其他内容,这不是问题。如果它在通用机器上运行,那将是一个问题。

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

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

关于c++ - 与 linux 信号/条件变量相比的缓存一致性开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34507065/

相关文章:

c++ - 适用于集合的 std::async 变体

c++ - 为什么空行缩进不好?

c++ - 使用 ECB 操作模式的 OpenSSL 库进行 AES-256 加密

java - 通过此与虚拟对象同步

Java多线程阅读资料

c# - 为什么这个 Parallel.ForEach 循环没有提高性能?

c++ - 使用 LibVLC 在播放时保存流

android - shell 无法使用 > 和 >> 捕获文件中的输出

linux - 如何检查 Xorg 是否在 emacs lisp 中运行?

linux - 在 bash 脚本中比较两个文件时没有这样的文件或目录错误