我一直在开发一个单独的基本模型。你所需要知道的就是个体的出生、繁殖和死亡。我有一个GUI,可以在其中看到这些过程的发生。
我有一个mac pro,有8个核心和16GB内存。
考虑到模拟必须重复几次才能得到误差条等,我想我可以运行主类,然后在不同的内核上运行单独的模拟(都从同一个程序运行(。易于理解的每个并行模拟都不知道其他模拟,因此不需要同步块。
当main方法运行时,它调用main类的构造函数,该构造函数创建其他对象并开始模拟。因此,为了并行化,我创建了一个固定的线程池,它将分别调用主类构造函数和多个(好吧,8个,核的数量(模拟。
但是,它运行得很慢,就像我在串行运行模拟一样。每个模拟的GUI中的动画按顺序更新,而不是同时更新。
事实上,如果我从命令行同时运行该程序8次(并在后台用"&"放置(,它会更快,行为也更像我希望的那样。这太令人恼火了!
在模拟开始时,执行一些IO操作以读入有关个人的数据,但仅在开始时执行。
有趣的是,"并行"进程创建的第一个对象是在相同的内存地址上创建的,但我认为这不是问题。
如果有人从java并发工具中了解到这种性能的不足,那么为什么程序看起来是串行运行的,以及为什么简单地从命令行运行主方法8次比尝试并行化要好,这将是最有帮助的。
因为坦率地说,我对java的并行化能力失去了信心。
干杯
James
noOfProcessors = (byte)Runtime.getRuntime().availableProcessors();
ExecutorService eservice = Executors.newFixedThreadPool( noOfProcessors );
List<Future> futuresList = new ArrayList<Future>();
for( int i = 0; i < noOfProcessors; i++ ){
futuresList.add( eservice.submit( new simulation() ) );
}//end for
for( Future future : futuresList ){
try{
future.get();
}catch( InterruptedException ex ){
Logger.getLogger( simPanel.class.getName() ).log( Level.SEVERE, null, ex );
System.exit( 1 );
}catch( ExecutionException ex ){
Logger.getLogger( simPanel.class.getName() ).log( Level.SEVERE, null, ex );
System.exit( 1 );
}//end try-catch
}//end for loop
虽然不太熟悉Java的Executors类,但串行行为似乎表明线程池在同一处理器上运行所有线程。也许这与JVM如何处理线程有关?无论如何,看看您是否可以在Java中创建单独的进程,看看这是否有什么不同。