条件变量的成本是多少?

发布于 2024-11-03 03:48:17 字数 199 浏览 5 评论 0原文

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

编辑:既然涉及到内核调用,那么内核调用比常规函数调用要贵多少?

Assume that unused execution resources are available on the machine in question, i.e. not all CPUs are being utilized. If a thread is waiting on a condition variable, what are the costs associated with waking up this thread? Similarly, what are the costs associated with waiting on a condition variable? I'm interested in both a rough quantification and where the costs come from. To the extent that the answer is "it depends", I primarily care about recent versions of Windows and Linux on x86/x64.

Edit: Since kernel calls are involved, how much more expensive is a kernel call than a regular function call?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌伤浅笑 2024-11-10 03:48:17

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

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

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

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

I don't know any details about the pthreads or D implementations, but in general terms, the best-case overhead for a condition variable is one extra kernel call and possible context switch.

A typical implementation is just a wrapper around events and mutexes, and so the overhead and timings can be characterized by the behavior of those kernel objects. On waiting the thread gives up the remainder of its scheduled time quantum and on waking up the thread gets scheduled by the kernel and gets the next available time quantum, based on its priority. This depends heavily on load and kernel configuration, but will typically be within a few milliseconds.

For a condition variable, there's then the additional task of re-acquiring the mutex, which of course could block. If it doesn't block, then it's still a kernel call. This may end up being optimized down to a few atomic CPU instructions which are very fast by comparison, but are limited to a single process. [ed: a CRITICAL_SECTION in Win32 or a futex in Linux, for example.]

The worst case is that the condition variable is spuriously triggered and the thread wakes up only to find that there's nothing to do, but that typically accounts for a negligible fraction of the total overhead.

九局 2024-11-10 03:48:17

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

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

我们没有测试 futexes。

This is related to your question although I don't think it is the answer you are looking for.

We benchmarked signals vs mutex/conditons to see which method could sleep and wake a thread faster. For the signals, we used sigwait() to suspend and pthread_kill to wake. For the mutex/conditions We used one mutex and one condition for each thread. We found that we could sleep and wake threads 5x faster using signals.

We did not test futexes.

陈年往事 2024-11-10 03:48:17

回答你的最后一个问题:

既然涉及到内核调用,那么内核调用比普通函数调用要贵多少?

是的,大约贵1000倍。

To answer your final question:

Since kernel calls are involved, how much more expensive is a kernel call than a regular function call?

Yes, roughly 1000 times more expensive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文