2013-02-19 50 views
2

我试图使用工作线程来加速更大的算法,当我发现在更多的线程上使用独立的优先级队列实际上会降低性能。于是我写了一个小测试用例。缓慢的工作线程性能与优先级队列

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

我把测试用例here,因为它比片段更长。 (处理器关联位来自NCrunch

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

无论如何,如果我用一个线程和一个核心运行程序,它会获得大约100%的使用率。 One core 两根线程/两个核心的使用率下降 Two cores 最终,所有8个核心的使用率降至30%。 eight cores

这是一个问题,因为性能的下降会使任何操作都无效,这将会从多线程中获益。什么导致性能下降?每个队列完全独立于另一个线程

+0

如果您运行的物理内核很少(并且启用了超线程),那可能都是正常的。请参阅http://superuser.com/questions/133082/hyper-threading-and-dual-core-whats-the-difference和http://superuser.com/questions/420329/single-threaded-program-takes-too -low-cpu – 2013-02-19 16:53:11

+0

嗯,我将不得不尝试禁用超线程。但是,如果我做一些像http://stackoverflow.com/questions/39395/how-do-i-calculate-pi-in-c计算Pi,我全面获得100%。 – Tocs 2013-02-19 17:02:48

+0

@Tocs请发布你的结果 - 我一直有类似的问题,并没有意识到超线程可能是责备。 – AngryHacker 2013-02-19 17:44:48

回答

2

像解决pi问题更适合于并行化,超线程可以让你加快速度。当你正在处理像你这样的沉重记忆问题时,超线程无法帮助并且实际上可能会受到伤害。检查CPU架构中的“流水线”。

通过使用2-cpus可以获得2x加速的实际问题并不多。越多cpus,开销越大。在您的测试案例算法中,我怀疑内核不得不等待内存子系统。如果您调整了内存需求,当您将内存需求移至CPU高速缓存大小时,您会看到性能(和利用率)的增加。

+0

我可以看到这是一个问题,队列的堆不完全是在内存中的本地。它经常分配一小部分内存,因此分散。我会试着找到一个更加缓存友好的堆实现,看看它是否改善了它。 – Tocs 2013-02-19 18:32:33

+0

对于某个与优先级队列有相同问题的人,我写了一个QuickHeap的粗略实现,它是一个缓存遗忘的堆。这意味着它可以在不知道大小的情况下优化使用缓存。 http://pastie.org/6316709。使用这个优先级队列时,我看到几乎100%的CPU使用率,同时推动和弹出。记忆确实是个问题。 – Tocs 2013-02-22 14:26:13

0

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

此外,当您说“性能下降”时,您是否检查过系统正在创建多少个争用?您可能也正在减轻线程间的争用。