【问题标题】:Slow worker thread performance with priority queue优先级队列的工作线程性能缓慢
【发布时间】:2013-02-20 01:38:51
【问题描述】:

当我注意到在更多线程上使用独立优先级队列实际上会降低性能时,我正试图使用​​工作线程来加速更大的算法。所以我写了一个小测试用例。

我在其中查询要启动多少个线程,将每个线程设置为自己的处理器,并从我的优先级队列中推送和弹出很多东西。每个线程都有自己的优先级队列,它们是单独分配的,所以我不怀疑错误共享。

我放了测试用例here,因为它比sn-p长。 (处理器亲和位来自NCrunch

优先级队列是我自己创建的,因为 .NET 没有内置队列。如果这有什么不同,它会使用Pairing Heap

无论如何,如果我用一个线程和一个内核运行程序,它的使用率大约是 100%。 两个线程/两个内核的使用率下降 最终将所有 8 个内核的使用率降至 30%。

这是一个问题,因为性能下降抵消了多线程带来的任何好处。是什么导致性能下降?每个队列完全独立于其他线程的

【问题讨论】:

标签: c# priority-queue worker-thread pairing-heap


【解决方案1】:

解决 pi 等一些问题更适合并行化,而超线程实际上可以加快速度。当您处理像您这样的严重内存问题时,超线程无济于事,实际上可能会造成伤害。查看 CPU 架构中的“流水线”。

没有多少实际问题可以通过使用 2-cpus 获得 2 倍的加速。 cpu 越多,开销越大。在您的测试用例算法中,我怀疑内核必须等待内存子系统。如果您调整内存要求,您将看到性能(和利用率)随着您将内存要求移近 CPU 缓存大小而提高。

【讨论】:

  • 我可以看到这是一个问题,队列的堆在内存中并不完全是本地的。它经常分配的小块内存,所以它会分散。我会尝试找到一个对缓存更友好的堆实现,看看是否能改进它。
  • 对于优先级队列有同样问题的人,我编写了一个 QuickHeap 的粗略实现,它是一个缓存遗忘堆。这意味着它可以在不知道缓存大小的情况下优化使用缓存。 pastie.org/6316709。使用这个优先级队列,我在推送和弹出时看到几乎 100% 的 CPU 使用率。内存确实是个问题。
【解决方案2】:

操作系统正在将处理分配给它希望的任何 CPU。因此,您会看到每个处理器都在做一些工作。

此外,当您说“性能下降”时,您是否检查过系统正在创建多少争用?您可能也正在从线程之间的争用中解脱出来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多