【问题标题】:What are the costs of a condition variable?条件变量的成本是多少?
【发布时间】:2011-08-09 19:22:02
【问题描述】:

假设有问题的机器上有未使用的执行资源,即并非所有 CPU 都在使用。如果一个线程正在等待一个条件变量,那么唤醒这个线程的相关成本是多少?同样,等待条件变量的相关成本是多少?我对粗略的量化和成本的来源都很感兴趣。就答案是“视情况而定”而言,我主要关心 x86/x64 上的最新版本的 Windows 和 Linux。

编辑:由于涉及内核调用,内核调用比常规函数调用贵多少?

【问题讨论】:

  • @Tim:我实际上对 D 的 core.sync.condition 原语很感兴趣,但我把它省略了,因为我怀疑这里的很多人都熟悉它。
  • 啊,我删除了我的问题,因为我看到你添加了一个 pthreads 标签。那是因为core.sync.condition 是用pthreads 实现的吗?
  • @Tim:在 Linux 上,我很确定。

标签: multithreading concurrency synchronization pthreads condition-variable


【解决方案1】:

我不知道有关 pthread 或 D 实现的任何细节,但总的来说,条件变量的最佳情况开销是一个额外的内核调用和可能的上下文切换。

典型的实现只是事件和互斥体的包装,因此开销和时间可以通过这些内核对象的行为来表征。在等待线程放弃其预定时间量的剩余部分,并在唤醒线程由内核调度并根据其优先级获得下一个可用时间量。这在很大程度上取决于负载和内核配置,但通常会在几毫秒内。

对于条件变量,还有重新获取互斥锁的额外任务,这当然可能会阻塞。如果它没有阻塞,那么它仍然是内核调用。这可能最终被优化为几个原子 CPU 指令,相比之下这些指令非常快,但仅限于单个进程。 [编辑:例如 Win32 中的 CRITICAL_SECTION 或 Linux 中的 futex。]

最坏的情况是条件变量被虚假触发,线程醒来后发现无事可做,但这通常占总开销的一小部分。

【讨论】:

  • Linux 与 Windows 一样,也支持快速用户空间互斥锁。只有在阻塞时才会涉及内核。
【解决方案2】:

回答你的最后一个问题:

由于涉及内核调用,内核调用比常规函数调用贵多少?

是的,大约贵 1000 倍。

【讨论】:

    【解决方案3】:

    这与您的问题有关,尽管我认为这不是您要寻找的答案。

    我们对信号与互斥体/条件进行了基准测试,以了解哪种方法可以更快地休眠和唤醒线程。对于信号,我们使用 sigwait() 暂停并使用 pthread_kill 唤醒。对于互斥体/条件我们为每个线程使用了一个互斥体和一个条件。我们发现使用信号可以将线程睡眠和唤醒速度提高 5 倍。

    我们没有测试 futex。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多