我使用一个软件(anylogic)导出可运行的jar文件,这些文件本身使用不同的参数重复运行一组模拟(所谓的参数变化实验)。我正在运行的模拟具有非常高的ram密集度,因此我必须限制jar文件可用的内核数量。在anylogic中,可用内核的数量很容易设置,但是通过服务器上的linux命令行,我知道的唯一方法是使用 taskset
命令手动指定要使用的可用内核(使用cpu关联“掩码”)。到目前为止,这已经很好地工作了,但是由于您必须指定要使用的各个核心,因此我了解到,根据您选择的核心,性能可能会有相当大的差异。例如,您可能希望最大限度地利用cpu缓存级别,因此如果选择共享过多缓存的内核,则性能会降低很多。
因为anylogic是用java编写的,所以我可以使用java代码来指定模拟的运行。我正在考虑使用javaexecutorservice构建一个单独运行的池,这样我就可以将池的大小指定为与我正在使用的机器的ram相匹配的核数。我认为这会带来很多好处,最重要的是,也许计算机的scehduler可以更好地选择内核以最小化运行时间。
在我的测试中,我构建了一个小的anylogic模型,运行大约需要10秒(它只是在两个状态图状态之间反复切换)。然后我用这个简单的代码创建了一个定制的实验。
ExecutorService service = Executors.newFixedThreadPool(2);
for (int i=0; i<10; i++)
{
Simulation experiment = new Simulation();
experiment.variable = i;
service.execute( () -> experiment.run() );
}
我希望看到的是只有2个 Simulation
对象一次启动,因为这是线程池的大小。但我看到所有10个线程都启动并在2个线程上并行运行。这让我觉得上下文转换正在发生,我认为这是非常低效的。
什么时候,而不是调用anylogic Simulation
,我只是在 service.execute
功能,似乎工作正常,显示只有2个 Tasks
一次跑步。
public class Task implements Runnable, Serializable {
public void run() {
traceln("Starting task on thread " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
traceln("Ending task on thread " + Thread.currentThread().getName());
}
}
有人知道为什么anylogic函数会同时设置所有的模拟吗?
暂无答案!
目前还没有任何答案,快来回答吧!