C# 什么时候更细粒度的锁定对性能更好?

C# 什么时候更细粒度的锁定对性能更好?,c#,multithreading,.net-4.0,locking,C#,Multithreading,.net 4.0,Locking,最近,我尝试使用跳过列表数据结构实现并发优先级队列——出于这个问题的考虑,如果您不知道什么是跳过列表,我相信只要绘制一个链接列表就足够了。我尝试了最小的锁定(即允许同时进行多个入队和出队,如有必要,仅锁定节点或其前向指针,尽快释放锁,使用联锁的遍历列表等) 我对结果感到满意。然而,使用syncroot锁包围的add和remove编写常规skiplist(即在任何给定时间只允许一个操作)的速度实际上是原来的两倍 我假设我的实现中一定有bug。但是,即使是Microsoft网站上列出的“并发优先级队

最近,我尝试使用跳过列表数据结构实现并发优先级队列——出于这个问题的考虑,如果您不知道什么是跳过列表,我相信只要绘制一个链接列表就足够了。我尝试了最小的锁定(即允许同时进行多个入队和出队,如有必要,仅锁定节点或其前向指针,尽快释放锁,使用联锁的遍历列表等)

我对结果感到满意。然而,使用syncroot锁包围的add和remove编写常规skiplist(即在任何给定时间只允许一个操作)的速度实际上是原来的两倍

我假设我的实现中一定有bug。但是,即使是Microsoft网站上列出的“并发优先级队列”,实际上一次也只允许执行一个操作(即,在排队和退队时使用syncroot锁)

一般来说,(如果这个问题太笼统,请原谅我),在什么情况下更细粒度的锁定实际上会导致性能的提高?我想象在我的例子中,由于我实际上必须使用Interlocked.Exchange(有更好的方法吗?)以及多个测试、测试和集合等遍历大型列表,这会减慢排队和退队的速度


此外,是否有一个工具可以帮助我确定大部分时间花在哪里?谢谢。

同步越多,应用程序的性能损失就越大。 在复杂的情况下,使用syncroot可能会导致问题不是解决方法

诀窍是在同步中找到正确的平衡;足以使其可靠(如无条件)


查看System.Collections.Concurrent命名空间

同步越多,应用程序的性能损失就越大。 在复杂的情况下,使用syncroot可能会导致问题不是解决方法

诀窍是在同步中找到正确的平衡;足以使其可靠(如无条件)


查看System.Collections.Concurrent命名空间

经常检查锁定区域当前是否空闲,设置锁,然后在离开时释放锁,这会产生开销。如果在实践中,您很少真正与其他人竞争访问该关键部分,那么您只是出于没有任何有利的原因执行了该开销。另一方面,如果有很多线程试图使用您的数据结构,那么您可能会发现并行运行操作(如果您有多核CPU)所提高的性能超过了管理锁的开销


对于这些类型的数据结构,当执行通常不需要彼此等待的操作时,几十个线程都试图同时使用数据结构,这种情况非常少见。因此,简而言之,您可能会生成测试用例,通过添加线程并正确管理它们所做的工作,使较小的锁用例的性能更好。如果您当前的测试是您实际计划如何使用数据结构的合理表示,那么很明显,您的使用将不会受益于更精细的锁定方案。

经常检查锁定区域当前是否空闲,设置锁定,然后在离开时释放锁定,这会增加开销。如果在实践中,您很少真正与其他人竞争访问该关键部分,那么您只是出于没有任何有利的原因执行了该开销。另一方面,如果有很多线程试图使用您的数据结构,那么您可能会发现并行运行操作(如果您有多核CPU)所提高的性能超过了管理锁的开销

对于这些类型的数据结构,当执行通常不需要彼此等待的操作时,几十个线程都试图同时使用数据结构,这种情况非常少见。因此,简而言之,您可能会生成测试用例,通过添加线程并正确管理它们所做的工作,使较小的锁用例的性能更好。如果您当前的测试是您实际计划如何使用数据结构的合理表示,那么很明显,您的使用不会受益于更复杂的锁定方案