我最近编写了一个C#控制台时间表格算法,该算法基于遗传算法与几个暴力程序的组合。最初的结果很有希望,但我想我可以通过分裂粗暴来提高性能强制例程在多处理器体系结构上并行运行。为此,我使用了文档齐全的生产者/消费者模型(如本文http://www.albahari.com/threading/part2.aspx#_ProducerConsumerQWaitHandle中所述)。我改变了我的代码,在强力例程中为每个逻辑处理器创建一个线程。
我工作站的性能提升非常令人满意。我在以下硬件上运行Windows XP:
Intel Core 2 Quad CPU 2.33 GHz 3.49 GB RAM
初始测试显示使用4个线程时平均性能提升约40%。下一步是将新算法的多线程版本部署到更高规格的UAT服务器。这是我们的UAT服务器的规范:
Windows 2003 Server R2 Enterprise x64 8个CPU(四核)AMD Opteron 2.70 GHz 255 GB RAM
在运行第一轮测试后,我们都惊讶地发现算法在高规格的W2003服务器上实际运行速度比在我当地的XP工作站上慢!实际上,测试似乎表明生成了多少线程无关紧要(测试是在2到32个线程之间生成的应用程序中运行的)。在UAT W2003服务器上,该算法总是运行得慢得多?
怎么会这样?当然应用程序应该在8 cpu(四核)上比我的2 Quad工作站运行得更快?为什么我们看到W2003服务器上的多线程没有性能提升,而XP工作站测试显示增益高达40%?
任何帮助或指示都将不胜感激。
此致
迈尔斯
答案 0 :(得分:1)
你需要找出它花费时间的地方。它可能是像非常缓慢的控制台写入一样愚蠢吗?
听起来你也在x86和x64平台之间进行切换,但是你没有说你的.NET应用程序是如何编译的 - 它是在x64机器上以32位还是64位运行?
答案 1 :(得分:1)
这在很大程度上取决于您的代码和操作系统。没有检查代码就不可能回答你的问题。很容易出现多线程错误。
答案 2 :(得分:1)
我的猜测(由于缺乏信息,这是有限的)是由于真正的共享或更可能的错误共享,您可能会遇到问题。
由于缓存命中率过高,虚假共享很容易导致算法因添加更多内核而变慢。如果您的服务器具有更大的缓存行大小,则更有可能发生。
我特别怀疑这可能是问题所在 - 特别是因为你只有4个线程比1增加了40%。通常,你会获得一定的可扩展性,直到达到一个低阈值线程,然后开始获得导致perf的缓存命中未命中。急剧下降。这可能是个问题。
答案 3 :(得分:0)
40%的总加速意味着您的算法受内存带宽限制,或者您正在进行太多的同步。分析器可以在每种情况下提供帮助。
等待更多数据处理的每次调用都很昂贵。理想情况下,等待新数据或执行同步锁定/解锁所花费的CPU时间很少。确保这一点的简单方法是使您的处理负载尽可能“大”。
至于生产系统的减速 - 对其进行分析。这里有很多变数。