确定是否可以使用* only * CAS操作完成并发逻辑

时间:2013-12-02 07:17:43

标签: multithreading concurrency atomic compare-and-swap

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

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

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

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

  3. 粗略地说,我们可以说如果一块逻辑可以被分成几个相互依赖的状态,每个只需要CAS,那么这种逻辑只能通过CAS解决。但是应用于真正的问题似乎要复杂得多,而且我觉得缺乏一种好的方法来划分并确定这种逻辑划分是否可行。

    请与我分享您的经验或我不了解的任何方法。

1 个答案:

答案 0 :(得分:0)

经过多年使用原子学,这是我的非专业经验法则。

  1. 您的数据必须位于同一地点。
  2. 您的数据必须很小。
  3. 你不需要任何花哨的东西。
  4. 你需要精细的锁定。
  5. 你需要速度。
  6. 混合搭配。
  7. <强>同位 要使用原子,所有必须原子改变的数据都需要是连续的。因此,使用原子很难实现双链表,因为您必须同时更新不同节点上的指针。单个链表很简单。

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

    你不需要任何花哨的东西。 使用单个链接列表进行原子操作时,只能在列表前面添加和删除项目。如果您可以使用哈希表,单个链表,跳过列表或数组,则可以使用原子。 Atomics非常适合构建结构,然后以原子方式交换指向该结构的指针。

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

    <强>速度 与原子相比,互斥体是神可怕的慢。每次调用malloc时编写一个锁定互斥锁的内存分配器会很糟糕。我在大约3年前对互斥量与原子进行了基准比较,并且出现了40倍的放缓。

    混合搭配! 我使用互斥锁的地方,原子会在屁股和混淆中完全痛苦。我尝试将这些情况限制为执行不多的代码,因此我不会为性能损失付出代价。

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