【问题标题】:Lock free stack and queue in C#在 C# 中锁定空闲堆栈和队列
【发布时间】:2009-02-15 09:53:40
【问题描述】:

有谁知道是否有任何可用于 .NET 的无锁容器库?

最好是被证明有效且比我们在 .NET 中使用的同步包装器更快的东西。

我在 .NET 上找到了一些文章,但没有一篇指定任何速度基准测试,也没有激发人们对其可靠性的信心。

谢谢

【问题讨论】:

  • 请跟进并发布您可能在您可能测试过的无锁结构上发现的任何性能相关数据。
  • 我们最终推出了自己的容器,主要基于 boyet.com/index.html。使用无锁容器与标准容器相比,我们处理样品批次所需的总时间(平均)减少了约 12%。总而言之,我会说这不值得:-(
  • 我遇到了Ariadne,它有这些。我很难理解代码。对于像for(;;){...some code...} 这样的语句,它有一些古怪的空,并且它里面会有一个return 语句。它在顶部有一条评论说:“考虑到 4.0 FCL 已经有一个无锁队列,这个队列主要用于完成或用于库中的其他类。Mono 实现非常接近这一点,而MS 实现更复杂,但应该更好地利用 CPU 缓存..."
  • @LouisSomers 我不像古板那么古怪;尽管while(true) 在今天可能更流行,但前者在我看来是“永远”,而后者对我来说是“而宇宙的基本逻辑规则”,这让我有点不安。自从那条评论之后,我确实在 FCL 之外添加了一些功能,我应该对其进行编辑,但我想我会保留它,直到今年晚些时候进行更彻底的审查。
  • @LouisSomers 我对“古怪”很满意,该库中的某些代码在速度方面确实有些古怪(goto 在手动编码的尾调用消除中)或古怪因为与不必考虑并发性的自然状态相比,状态转换是不寻常的。 while(true)for(;;) 虽然完全相同,但纯粹是风格问题。 for(;;) 在 K&R 和 Stroustrup 的 C++ 书中使用,但 while(true) 后来变得更流行,所以 for(;;) 只是更老式。 (还有一些旧工具会抱怨这个常量,虽然不是在 C# 中)...

标签: .net multithreading data-structures synchronization lock-free


【解决方案1】:

迟到了,但总比没有好,我认为我会将 Julian Bucknalls 的文章添加到此列表中。

但他没有性能数据。在我对他的结构的测试中,与锁定相比,该列表的扩展性很好(与 ReaderWriterLock 相比,内核使用率非常低)。

他的博客有一系列关于 C# 中的无锁结构的文章。

LOCK-FREE DATA STRUCTURES: THE STACK

【讨论】:

  • 内核使用与他使用的 CAS 无关。 CAS 是重量级的锤子,但在 CLR 中,您目前几乎没有太多选择。
  • 与 ReaderWriterLock 相比,CAS 在内核时间上很轻。比较两个循环。一个将使用所有用户空间时间,另一个将使用所有内核时间。
  • 你实际上不能做一个无锁堆栈,除非你事先知道你的元素不会被删除。我相信 C# 会进行垃圾收集(它消除了使用无锁的一些要点!)所以你可以摆脱它。但在 C 语言中,我认为堆栈已损坏,pop 中存在正常的错误。
  • 顺便说一句,我关于堆栈被破坏的评论是完全错误的。
  • @Blank Xavier。不完全。如果你要对 C 或 C++ 做一个幼稚的移植,它会被破坏,并且很难做一个“适当的”移植,因为你必须找到一些方法来处理 C# 可能依赖于 GC 处理的东西。所以是的,您的评论是错误的,但并非“完全”错误,因为它确实解决了关于算法所依赖的运行时条件的重要问题。
【解决方案2】:

你的意思是像它们存在于 PFX 框架(Parallels for .NET)、ConcurrentQueue 和 ConcurrentStack 中的容器类

Pfx blog

【讨论】:

  • PFX 看起来不错,但文档似乎暗示 ConcurrentQueue 和 ConcurrentStack 使用锁来提供线程安全
  • 我会不惜一切代价避免使用 PFX。我们看到了 8 倍(没错)的退化,然后才意识到它真的不会给你任何东西,一本好书不会教你做得更好。..
  • @Radu094:Joe Duffy 的《Windows 上的并发编程》一书中指出,ConcurrentQueue 目前是无锁的。 @rama-jka toti:.NET 4 中的东西比 CTP 的要好得多,但我还没有针对替代品测试过无锁数据结构。当然,它们仍然比不安全的线程慢得多。
  • 这里有一个很好的讨论,这意味着写入(添加到)并发集合更慢并且使用锁定,但从它们读取不会并且更快...albahari.com/threading/part5.aspx#_Concurrent_Collections
  • @dodgy_coder 那篇文章考虑了一个作者,多个读者的情况。在多个写入者、多个读取者的情况下,我希望并发集合的写入速度也会快得多。
【解决方案3】:

在对此一无所知的情况下,我偶然发现了一个库here

虽然可能不是你要找的,但至少有一个关于 lock free queue structure in C# here 的 StackOverflow 的实现和讨论。完成 StackOverflow 代码审查过程可能会对其安全性产生一些信心,或提供有关如何自行构建无锁容器的信息。

【讨论】:

    【解决方案4】:

    无锁数据结构会出现问题,直到它们使用由内存模型引起的混乱来修改 CLR,请参阅 CLI 规范。

    无锁编程非常困难,顺便说一句,您不应该在集合(容器)级别上操心它。对任何语言都适用..

    【讨论】:

    • 您能否详细说明“修改 CLR”?你觉得哪里不对?
    • 他试图暗示 CLR 做出的保证足够弱。虽然 CLR 内存模型并不容易掌握并且可能会导致复杂性,但这并不意味着我们不能设计防弹容器。
    猜你喜欢
    • 1970-01-01
    • 2013-09-18
    • 2015-12-22
    • 2014-07-21
    • 2015-11-16
    • 2019-03-07
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多