【问题标题】:Determine if concurrency logic can be done using *only* CAS operations确定是否可以使用 *only* CAS 操作来完成并发逻辑
【发布时间】:2013-12-02 07:17:42
【问题描述】:

对于高性能多线程系统,是否有确定性的方式/方法来确定可以使用 only 比较和交换(也称为原子操作)来完成哪些并发逻辑,哪些必须使用锁,信号机和/或障碍?

我的系统总是涉及很多并发和多线程问题。有些很简单,如果快速需要一个简单的锁就可以解决;但是对于一些复杂的问题,或者将性能推向极限的试验,我发现我没有一致的确定性方法来判断问题是否可以仅使用 CAS 来解决。举个例子:

  1. 典型的生产者/消费者模型。并发队列只能使用 CAS 解决问题。

  2. 生产者/消费者模型有很多更新,但消费混合。在这种情况下,如果使用双缓冲,则必须应用读/写锁;但是,如果我们使用三重缓冲,那么基本上可以使用 CAS。

粗略地说,我们可以说如果一个逻辑可以分成几个相互依赖的状态,每个状态只需要CAS,那么这样的逻辑可以只用CAS来解决。实际问题似乎要复杂得多,我确实觉得缺乏一种好的方法来划分和确定这种逻辑划分是否可能。

请分享您的经验或任何我不知道的方法。

【问题讨论】:

  • 您是在问是否使用 CAS 将any 基于锁的并发算法转换为无锁或无等待并发算法?
  • 不,我的观点是:给定某种基于锁的算法,是否有系统的方法来确定是否可以将其转换为纯基于 CAS 的无等待算法。
  • 如果你在谈论通用结构,那么是的。任何基于锁的数据结构都可以无锁并最终无等待。但是这种通用构造效率低下,只是用来证明事情是可以做到的。如果你想要效率,那么你必须定制设计每个算法。 Maurice Herlihy 的论文 Impossibility and universality results for wait-free synchronization 讨论了这一点

标签: multithreading concurrency atomic compare-and-swap


【解决方案1】:

这是我多年使用原子后的外行经验法则。

  1. 您的数据必须位于同一地点。
  2. 您的数据必须很小。
  3. 您不需要任何花哨的东西。
  4. 您需要细粒度的锁定。
  5. 您需要速度。
  6. 混搭。

位于同一地点。 要使用原子,必须以原子方式更改的所有数据都必须是连续的。因此,双链表对于原子来说几乎是不可能的,因为您必须同时更新不同节点上的指针。单个链表是微不足道的。

小。 小意味着与系统允许的最大原子操作一样小。要使用原子更新结构中的 50 个字段,您需要创建新结构,然后以原子方式交换指向它的指针。

你不需要任何花哨的东西。 当以原子方式使用单链表时,您只能从列表的前面添加和删除项目。如果您可以使用哈希表、单链表、跳过列表或数组来做到这一点,那么您可以使用原子。原子非常适合构建结构,然后以原子方式交换指向该结构的指针。

您需要细粒度的锁定。 例如,使用原子哈希表,您可以在存储桶级别而不是列表级别“锁定”。我想你可以每个桶有一个互斥锁。

速度。 与原子相比,互斥锁真是太慢了。每次调用 malloc 时编写一个锁定互斥锁的内存分配器会很糟糕。大约 3 年前,我对 mutex 与 atomic 进行了基准测试,得出了 40 倍的减速。

混搭! 我在原子将是一个彻头彻尾的痛苦和混淆的地方使用互斥锁。我尝试将这些情况限制在执行不多的代码上,因此我不会为性能损失买单。

所有这些限制都在说我很容易在所有热点中使用原子,并且很少需要回退到互斥锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 2016-05-16
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    相关资源
    最近更新 更多