locking已解锁的互斥锁效率如何? 互斥体的成本是多less?
在低级语言(C,C ++或其他)中,我有两种互斥方式(比如pthread给我或者本地系统库提供的任何东西)或者一个对象的select。
locking互斥锁效率如何? 也就是说,有多less汇编程序指令可能会有多less时间(在互斥锁被解锁的情况下)?
互斥体花费多less钱? 真的有很多互斥体是一个问题吗? 或者我可以在我的代码中插入尽可能多的互斥variables,因为我有int
variables,这并不重要吗?
(我不确定不同的硬件之间有多大的差别,如果有的话,我也想知道它们,但是大多数时候我对硬件很感兴趣。
重点是,通过使用许多互斥体,每个互斥体只覆盖对象的一部分,而不是整个对象的单个互斥体,我可以安全地阻止许多块。 我想知道我应该走多远。 也就是说,我应该尽可能地尽可能地保护任何可能的块,不pipe这个复杂多less,这个互斥量是多less?
我有select之间有一堆互斥或一个单一的对象。
如果你有很multithreading并且经常访问对象,那么多个锁将增加并行性。 以可维护性为代价,由于更多的locking意味着更多的lockingdebugging。
locking互斥锁效率如何? 也就是说,有多less汇编程序指令可能会有多less时间(在互斥锁被解锁的情况下)?
精确的汇编程序指令是互斥量最小的开销 – 内存/高速caching一致性保证是主要开销。 less一些特定的locking – 更好。
互斥体由两个主要部分组成(过度简化):(1)表示互斥锁是否locking的标志;(2)等待队列。
标志的更改只是几条指令,通常在没有系统调用的情况下完成。 如果互斥锁被locking,则系统调用会将调用线程添加到等待队列中,并开始等待。 解锁,如果等待队列是空的,便宜,但否则需要一个系统调用来唤醒其中一个等待进程。 (在某些系统上,使用廉价/快速的系统调用来实现互斥锁,只有在争用的情况下,它们才会变成缓慢(正常)的系统调用。)
locking解锁的互斥锁真的很便宜。 无争议的解锁互斥也很便宜。
互斥体花费多less钱? 真的有很多互斥体是一个问题吗? 或者我可以在我的代码中插入尽可能多的互斥variables,因为我有intvariables,这并不重要?
你可以根据需要在代码中插入尽可能多的互斥variables。 您只受限于应用程序可以分配的内存量。
概要。 用户空间锁(特别是互斥锁)便宜,不受任何系统限制。 但是其中太多拼写噩梦debugging。 简单的桌子:
- 更less的锁意味着更多的争用(缓慢的系统调用,CPU停滞)和较less的并行性
- 更less的锁意味着debuggingmultithreading问题的问题更less。
- 更多的锁意味着更less的争用和更高的并行性
- 更多的锁意味着更多的机会运行到不可解锁的死锁。
应该find并维护一个平衡的应用程序lockingscheme,通常平衡#2和#3。
(*)locking较less的互斥锁的问题在于,如果在应用程序中locking了太多的locking,会导致大部分CPU /内核stream量从其他CPU的数据caching中清除互斥锁内存,以确保caching一致性。 caching刷新就像轻量级的中断,并透明地由CPU处理 – 但是它们引入了所谓的分区 (search“分区”)。
而且这些档位使locking代码运行缓慢,通常没有任何明显的迹象表明为什么应用程序很慢。 (一些拱形提供了CPU /核心间的stream量统计,有些则不是。)
为了避免这个问题,人们通常使用大量的锁来降低锁争用的概率,避免失速。 这就是为什么不存在系统限制的廉价用户空间locking的原因。
这取决于你实际称之为“互斥体”,操作系统模式等。
至less这是一个互锁内存操作的成本。 这是一个比较繁重的操作(与其他原始汇编程序命令相比)。
但是,这可能会更高。 如果你称之为“互斥”一个内核对象(即由OSpipe理的对象)并在用户模式下运行,那么它的每一个操作都会导致一个非常繁重的内核模式事务。
例如在Intel Core Duo处理器,Windows XP上。 联锁操作:大约需要40个CPU周期。 内核模式调用(即系统调用) – 大约2000个CPU周期。
如果是这种情况 – 你可以考虑使用关键部分。 它是内核互斥和互锁内存访问的混合体。
成本将根据实施情况而有所不同,但您应该牢记两件事:
- 成本将很可能是最小的,因为它是一个相当原始的操作,并会因其使用模式( 大量使用 )而尽可能地优化。
- 不要紧,因为如果你想要安全的multithreading操作,你需要使用它。 如果你需要它,那么你需要它。
在单处理器系统上,通常可以禁止足够长的中断来自动更改数据。 多处理器系统可以使用testing和设置策略。
在这两种情况下,说明都相对有效。
至于你是否应该为一个庞大的数据结构提供一个单一的互斥体,或者是为每一个互斥体分配一个互斥体,这是一个平衡的行为。
通过拥有一个互斥量,multithreading之间的争用风险就更高。 您可以通过每个部分有一个互斥体来降低这种风险,但是您不想陷入一个线程必须locking180个互斥锁才能完成其工作的情况:-)