multithreading - 锁定和解锁互斥体的效率如何?互斥体的成本是多少?

标签 multithreading locking mutex blocking

在低级语言(C、C++ 或其他语言)中:我可以选择使用一堆互斥体(就像 pthread 给我的或 native 系统库提供的任何东西)或对象的单个互斥体。

锁定互斥体的效率如何? IE。可能有多少条汇编指令以及它们需要多少时间(在互斥锁未锁定的情况下)?

互斥体的成本是多少?拥有大量互斥锁会带来问题吗?或者我可以在代码中抛出与 int 变量一样多的互斥变量,这并不重要吗?

(我不确定不同硬件之间有多少差异。如果有的话,我也想了解它们。但主要是,我对通用硬件感兴趣。)

关键是,通过使用许多互斥体(每个互斥体仅覆盖对象的一部分)而不是整个对象的单个互斥体,我可以保护许多 block 。我想知道我应该在这件事上走多远。 IE。我是否应该尝试尽可能地保护任何可能的 block ,无论这意味着多么复杂以及多少互斥体?

<小时/>

WebKits blog post (2016) about locking与这个问题非常相关,并解释了自旋锁、自适应锁、futex等之间的区别。

最佳答案

I have the choice in between either having a bunch of mutexes or a single one for an object.

如果你有很多线程并且对对象的访问经常发生,那么多个锁会增加并行度。以可维护性为代价,因为更多的锁定意味着更多的锁定调试。

How efficient is it to lock a mutex? I.e. how much assembler instructions are there likely and how much time do they take (in the case that the mutex is unlocked)?

精确的汇编指令的开销最少为 a mutex -the memory/cache coherency担保是主要的开销。并且更少地使用特定的锁 - 更好。

互斥体由两个主要部分组成(过于简单化):(1) 指示互斥体是否锁定的标志,以及 (2) 等待队列。

标志的更改只需几条指令,通常无需系统调用即可完成。如果互斥量被锁定,系统调用将发生将调用线程添加到等待队列并开始等待。如果等待队列为空,则解锁很便宜,但否则需要系统调用来唤醒等待进程之一。 (在某些系统上,廉价/快速的系统调用用于实现互斥体,只有在发生争用的情况下它们才会变成慢速(正常)系统调用。)

锁定未锁定的互斥量确实很便宜。解锁互斥锁而不发生争用也很便宜。

How much does a mutex cost? Is it a problem to have really a lot of mutexes? Or can I just throw as much mutex variables in my code as I have int variables and it doesn't really matter?

您可以根据需要在代码中添加任意数量的互斥变量。您仅受应用程序可以分配的内存量的限制。

摘要。用户空间锁(尤其是互斥体)很便宜并且不受任何系统限制。但它们太多会给调试带来噩梦。简单表格:

  1. 更少的锁意味着更多的争用(缓慢的系统调用、CPU 停顿)和更少的并行性
  2. 锁越少意味着调试多线程问题的问题就越少。
  3. 更多的锁意味着更少的争用和更高的并行性
  4. 更多的锁意味着更多的机会遇到无法调试的死锁。

应该找到并维护应用程序的平衡锁定方案,通常平衡#2和#3。

<小时/>

(*) 较少锁定互斥体的问题是,如果您的应用程序中有太多锁定,则会导致大量 CPU/核心间流量从其他 CPU 的数据缓存中刷新互斥体内存以保证缓存的一致性。缓存刷新就像轻量级中断并由 CPU 透明地处理 - 但它们确实引入了所谓的 stalls (搜索“摊位”)。

停顿是导致锁定代码运行缓慢的原因,通常没有任何明显的迹象表明应用程序运行缓慢。 (有些架构提供 CPU/核心间的流量统计信息,有些则不提供。)

为了避免这个问题,人们通常采用大量的锁来减少锁争用的可能性并避免停顿。这就是为什么存在不受系统限制的廉价用户空间锁定的原因。

关于multithreading - 锁定和解锁互斥体的效率如何?互斥体的成本是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3652056/

相关文章:

java - 线程转储 : How to see the condition of waiting/or any other condition?

ios - sqlite优化读取性能

linux - 为什么 Pthread Mutex 不是异步信号安全的?

python - 从另一个线程调用线程中的方法,python

java - 谁调用了 wait() 方法,主线程或用于调用 wait() 的实例

java - 使用 java(Threads) 从方法返回值

使用 "private final Lock"的 Java 锁定和同步结果不相同

C# 多线程代码问题损坏数据

embedded - ARM 皮层 : mutex using bit banding

cron - 单个 Cron 实例/互斥体