【问题标题】:synchronization primitives: Equal latencies between atomics and mutex lock同步原语:原子和互斥锁之间的延迟相等
【发布时间】:2022-01-18 03:07:40
【问题描述】:

我正在努力提高我对 C++ 中同步原语的理解。我测量了各种并发操作的延迟,例如:

  • 对于原始std::mutex.unlock().lock() 返回之间的时间
  • 对于std::condition_variable.notify_one().wait() 返回之间的时间
  • 对于std::binary_semaphore.release().acquire() 之间的时间
  • 对于std::atomic_flag,从.clear().notify_one().wait() 以及从.test_and_set().notify_one().wait() 的时间

所有这些延迟都是相同的 (~4µs-15µs)。经过一番挖掘,我发现信号量是用原子实现的,而 condition_variables 归结为互斥体。所以它归结为原子与互斥体。在进入相关函数时(在 windows/MSVC 上),我发现 atomics 使用 Wait­On­Address/Wake­By­Address 而 mutex 使用 SRW 锁 (AcquireSRWLockExclusive)。

我天真地假设原子(尤其是 atomic_flag)具有最好的延迟特性,因为它们的功能非常有限。所以我的问题:

  • 为什么它们同样快?可能是我有限的测试。
  • Wait­On­Address/Wake­By­Address和SRW锁有什么区别?我认为它们都仅限于一个过程。我只在Wait­On­Address上找到了this article,但几乎没有涉及到与SRW锁的区别。

【问题讨论】:

    标签: c++ windows concurrency


    【解决方案1】:

    在非竞争状态下,SRWLock 只是一个原子int。因此,它的性能与atomic 相同也就不足为奇了。

    一旦您在测试中引入一些争用,您应该会看到非常不同的时间安排。

    SRWLock 本质上是 futex 的 Windows 版本 - 一种同步原语,在发生争用之前完全保留在用户空间中。

    Wait­On­Address / Wake­By­Address 和 SRWLock 在内部非常相似,但用例不同 - SRWLock 直接实现了 mutex/shared_mutexWait­On­Address / Wake­By­Address 对于 @987654330 更有用@。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多