多线程 – 锁定解锁互斥的效率如何?互斥量的成本是多少?

在一个低级语言(C,C或其他):我有两种选择之一:有一堆互斥(像什么pthread给我或任何本地系统库提供)或一个单一的对象。

锁定互斥体的效率如何?也就是说有多少汇编指令可能和他们需要多少时间(在互斥锁被解锁的情况下)?

互斥量是多少?是真的有很多互斥的问题吗?或者我可以只在我的代码中抛出尽可能多的互斥量变量,因为我有int变量,它没有什么关系吗?

(我不知道不同的硬件之间有多少差异如果有,我也想知道他们,但大多数情况下,我对常见的硬件感兴趣。)

关键是,通过使用多个互斥体,每个互斥体仅覆盖对象的一部分,而不是整个对象的单个互斥体,我可以安全地许多块。我想知道我应该走多远。也就是说我应该尝试尽可能安全的任何可能的块尽可能,无论多么复杂,多少互斥体这意味着什么?

最佳答案

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 mutexthe memory/cache coherency保证是主要开销。并且较少使用特定的锁 – 更好。

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

更改标志只是几个指令,通常没有系统调用。如果mutex被锁定,syscall将发生将调用线程添加到等待队列并开始等待。解锁,如果等待队列是空的,则是便宜的,但是否则需要系统调用来唤醒等待进程中的一个。 (在某些系统上,便宜/快速系统调用用于实现互斥,它们只在争用的情况下变成慢(正常)系统调用。)

锁定解锁互斥量真的很便宜。解锁互斥量w / o争用也很便宜。

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?

你可以抛出尽可能多的互斥变量到你的代码。你只受限于应用程序可以分配的内存量。

概要。用户空间锁(特别是互斥锁)价格便宜,不受任何系统限制。但是,他们中有太多人痴迷噩梦来调试。简单表:

>较少的锁意味着更多的争用(慢系统调用,CPU停止)和较少的并行性
>少锁意味着调试多线程问题的问题更少。
>更多的锁意味着更少的争用和更高的并行性
>更多的锁意味着更多的机会进入不可挽回的死锁。

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

(*)很少锁定互斥体的问题是,如果你的应用程序锁定太多,会导致大量的CPU间/内核流量从其他CPU的数据缓存刷新互斥体内存,以保证高速缓存一致性。缓存刷新像轻量级中断,并且由CPU透明地处理 – 但是它们引入所谓的stalls(搜索“stall”)。

而失速是什么使锁定代码运行缓慢,往往没有任何明显的指示为什么应用程序是慢的。 (一些arch提供了inter-CPU / core流量统计,有些没有。)

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

转载注明原文:多线程 – 锁定解锁互斥的效率如何?互斥量的成本是多少? - 代码日志