我写了一个遗传算法,为了优化它的性能,我决定对个体的适应度测试进行并行化。为了了解这对我的算法有什么影响,我重做了一次在并行化之前所做的测试,在那里我测试了GA在不断增长的种群规模下的性能。
并行版本的GA实际上比原始版本花费了大约50%的时间。我意识到有时并行化的开销实际上可能比节省的时间更多,但我怀疑这是否适用于这种情况-我的适应度测试是找到谢克尔散兵坑函数( http://extreme.adorio-research.org/download/mvf/html/node51.html )的全局最小值,而我的种群大小从10到1,000。我预计,在并行执行1000次sheckel散兵坑时,节省的时间将大大超过并行的开销。
所以我的问题是:为什么并行化会减慢算法的速度(而且如此显著)?
根据记录,我使用Java语言编写代码,并使用CountDownLatch并行化,它会等待所有线程(适应性测试)执行,然后再继续执行。
发布于 2012-06-16 10:58:46
所以我找出了问题所在--我以为我的体能测试花费了足够长的时间,并行是值得的,但事实完全不是这样。我填充了适应度测试,人为地延长了测试时间(这只是我用来监控GA性能的一个测试适应度测试),现在我看到了执行时间的显著差异-不断增长的人口规模导致执行时间延长了1000秒,而不是10秒。我应该指出的是,这是在实现Executor之前,正如所建议的那样。
感谢大家的帮助!
发布于 2012-06-15 07:01:22
根据你的评论,看起来你做的事情相当合理,也许除了线程的数量。但是你提到你用的是CountDownLatch,这让我开始思考...
我强烈建议您使用ExecutorService/Executors
进行并行化,而不是使用您自己的代码。让您的类成为一个Callable
,创建一堆这样的类,然后调用invokeAll()。通过这种方式,训练有素(不确定他们是否高薪)的专家完成了大部分编码工作。
使用Executors
,很容易控制线程的最大数量。您可以调用Runtime.availableProcessors()
来获得一次运行多少个线程的第一个通道,然后进行一些测试和调优。
编辑:刚刚发布了一个introduction to converting an algorithm to use ExecutorService.享受,欢迎评论/反馈。
发布于 2012-06-15 03:25:40
好吧,答案是它没有像你想象的那样并行化。问题是“为什么?”如果不看一下代码,答案将很难实现。但有一些明显的地方值得一看:
run()
方法而不是start()
方法。这听起来很愚蠢,但我已经被它咬到了。https://stackoverflow.com/questions/11039862
复制相似问题