【问题标题】:Circular buffer Vs. Lock free stack to implement a Free List圆形缓冲器与。锁定空闲堆栈以实现空闲列表
【发布时间】:2011-10-25 14:10:12
【问题描述】:

由于我一直在写一些多线程的代码,我想出了以下情况:

一个线程从内存池中声明一个资源单元,它处理它并将指向该数据的指针发送到另一个线程,以便使用循环缓冲区进行进一步操作(1R / 1W 情况)。

后者必须在处理完他收到的数据时通知前一个线程,以便回收内存。

我想知道将这个“Freelist”实现为另一个循环缓冲区 - 保存空闲资源的地址 - 或者选择无锁堆栈方式(在 x86-64 上实现 DCAS)是否更好 - 性能方面。 /p>

一般来说,这两种不同方法的优缺点是什么?

【问题讨论】:

  • '后者必须在处理完他收到的数据后通知前一个线程,以便回收内存' - 为什么?为什么消费者线程不能将实例/结构/任何东西回收到池本身?为什么生产者线程必须这样做?如果有多个池,(例如,如果每个生产者都有自己的池),您可以在 struct/instance/whatever 中传递池实例/func-pointer/whatever,(老实说,这种东西很多,使用 OO 语言要容易得多,而且我们的开发人员不必在 cmets 中键入长的“结构/实例/指针”字符串)。
  • 我对此很灵活:当我写这个问题时,我想到了一个模型,其中两个线程使用两个循环缓冲区来回通信。没有什么能阻止切换到它们都在内存池上运行的模型。我只是对这两种方法的优缺点感兴趣。

标签: c stack lock-free circular-buffer


【解决方案1】:

以防万一,无锁和无等待是有区别的。前者意味着没有锁定,但线程仍然可以忙于自旋而没有任何进展。后者意味着线程总是在没有锁定或忙于自旋的情况下取得进展。

对于一个读取器和一个写入器,实现无锁和无等待的 FIFO 循环缓冲区是微不足道的。

我听说后进先出堆栈也可以免等待,但对 FIFO 列表不太确定。听起来你需要一个队列而不是堆栈。

【讨论】:

  • 数据插入的顺序并不重要,我选择堆栈是因为它应该更易于管理。不过,我更喜欢尽可能处理循环缓冲区,但我正在收集想法。
【解决方案2】:

主要区别在于循环缓冲区是有界的,而堆栈则不是。

如果不进行测试,很难对此类事情做出性能判断。一方面,循环缓冲区由连续数组支持。如果读取器和写入器索引保持“接近”彼此,您将让每个线程不断地使共享缓存行无效。

另一方面,对于堆栈,您可能会争用堆栈顶部指针,从而导致线程有时会在 CAS 循环中旋转。

我的猜测是,最好的选择取决于工作负载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    相关资源
    最近更新 更多