遗传算法慢速算法的并行化显着。为什么会这样?

时间:2012-06-14 19:17:24

标签: java performance parallel-processing genetic-algorithm

我编写了一个遗传算法,并试图优化其性能,我决定将个人健身测试并行化。为了看看我在算法中做了哪些改变,我重新编写了在并行化之前完成的测试运行,我测试了GA在不断增长的人口规模中的表现。

GA的并行版本实际上比原始版本长约50%。我意识到有时并行化的开销实际上可能比节省时间更多,但我怀疑这应该适用于这种情况 - 我的健康测试是找到Sheckel的Foxholes函数的全局最小值(http://extreme.adorio-research.org/download/mvf/html/node51.html),我的人口规模在10到1000之间。我希望在1000次执行sheckel的散射孔的同时,节省的时间将大大超过并行化的开销。

所以我的问题是:为什么并行化会降低算法的速度(如此显着)?

为了记录,我使用Java进行编码,并且我使用CountDownLatch进行并行化,等待所有线程(适应性测试)在继续之前执行。

3 个答案:

答案 0 :(得分:3)

根据你的评论,看起来你做得相当合理,除了线程的数量。但是你提到你正在使用CountDownLatch让我思考...

我强烈建议您使用ExecutorService/Executors代替自己的代码进行并行化。将您的类设为Callable,创建一组,并调用invokeAll()。这种方式训练有素(不确定他们是否高薪)专家做了大部分编码。

使用Executors,可以很容易地控制最大线程数。您可以调用Runtime.availableProcessors()来获取一次运行多少个线程的第一次传递,然后进行一些测试和调整。

编辑:刚刚发布了introduction to converting an algorithm to use ExecutorService.享受,以及评论/反馈欢迎。

答案 1 :(得分:1)

好的,答案是它并没有像你想象的那样并行化。问题是“为什么?”如果不看代码,答案很难实现。但是有一些明显的地方可以看:

  • 确保(你会讨厌这个)你正在使用Thread的正确入口点。保证线程序列化而不告诉您事情的一种方法是调用run()方法而不是start()方法。这听起来很傻,但我被这个咬了。

  • 使用例如jconsole确保线程并发运行。如果没有,你就会意外地锁定某些东西。

  • 检查您同步的内容。检查您正在使用的集合类。其中一些根本不是线程安全的,其中一些是线程安全的,因为它们有内部同步。在线程之间共享的任何Collection类都可能是一种错误。

  • 如果没有任何消息,请与同事一起在纸上执行代码执行并手写出线程。

答案 2 :(得分:1)

所以我弄清楚问题是什么 - 我曾经认为我的健康测试需要足够长的时间才能实现,但完全没有。我填写了健身测试,人为地做了很长时间(这只是我用来监控GA表现的测试健身测试),现在我看到执行时间有显着差异 - 现在人口规模不断扩大将执行时间延长1000秒,而不是10秒。我应该指出,这是在实施执行程序之前,正如所建议的那样。

谢谢大家的帮助!