首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >遗传算法的并行化大大降低了算法的速度。为什么会这样呢?

遗传算法的并行化大大降低了算法的速度。为什么会这样呢?
EN

Stack Overflow用户
提问于 2012-06-15 03:17:24
回答 3查看 401关注 0票数 2

我写了一个遗传算法,为了优化它的性能,我决定对个体的适应度测试进行并行化。为了了解这对我的算法有什么影响,我重做了一次在并行化之前所做的测试,在那里我测试了GA在不断增长的种群规模下的性能。

并行版本的GA实际上比原始版本花费了大约50%的时间。我意识到有时并行化的开销实际上可能比节省的时间更多,但我怀疑这是否适用于这种情况-我的适应度测试是找到谢克尔散兵坑函数( http://extreme.adorio-research.org/download/mvf/html/node51.html )的全局最小值,而我的种群大小从10到1,000。我预计,在并行执行1000次sheckel散兵坑时,节省的时间将大大超过并行的开销。

所以我的问题是:为什么并行化会减慢算法的速度(而且如此显著)?

根据记录,我使用Java语言编写代码,并使用CountDownLatch并行化,它会等待所有线程(适应性测试)执行,然后再继续执行。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-16 10:58:46

所以我找出了问题所在--我以为我的体能测试花费了足够长的时间,并行是值得的,但事实完全不是这样。我填充了适应度测试,人为地延长了测试时间(这只是我用来监控GA性能的一个测试适应度测试),现在我看到了执行时间的显著差异-不断增长的人口规模导致执行时间延长了1000秒,而不是10秒。我应该指出的是,这是在实现Executor之前,正如所建议的那样。

感谢大家的帮助!

票数 1
EN

Stack Overflow用户

发布于 2012-06-15 07:01:22

根据你的评论,看起来你做的事情相当合理,也许除了线程的数量。但是你提到你用的是CountDownLatch,这让我开始思考...

我强烈建议您使用ExecutorService/Executors进行并行化,而不是使用您自己的代码。让您的类成为一个Callable,创建一堆这样的类,然后调用invokeAll()。通过这种方式,训练有素(不确定他们是否高薪)的专家完成了大部分编码工作。

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

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

票数 3
EN

Stack Overflow用户

发布于 2012-06-15 03:25:40

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

  • 确保(你会讨厌这个)你使用了正确的线程入口点。要保证线程能够序列化并且不会告诉您任何事情,一种方法是调用run()方法而不是start()方法。这听起来很愚蠢,但我已经被它咬到了。
  • 使用jconsole来确保线程完全是并发运行的。如果不是这样的话,你就会在同步的something.
  • check上得到一个意外的锁。检查您正在使用的集合类。它们中的一些根本不是线程安全的,还有一些是线程安全的,因为它们有内部同步。任何在线程之间共享的集合类都是可能的恶意者。
  • 如果没有结果,请与同事一起在纸上演示代码执行过程,并手写出线程。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11039862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档