工欲善其事必先利其器–SimpleTestBed

最近在研究一个近似的优化算法。在做对比实验的时候,一共要跑6,7个不同的算法来比较。为了公平起见,每个算法需要在几个不同的参数环境下,在 几批不同数据下,各自跑几十次,然后看看谁的评价效果最好。一共要跑大概上百次的算法运行。以前的做法是写一个脚本执行,或者说用JUnit之类的单元测 试工具来自动化跑。但是,现在的问题是,这上百次的测试,需要花太多时间了。而实际上,我们系有很多空闲的服务器,而且都是8 core和16 core的机器。于是,现在就有两个问题了:

1) 并行调度 。如果串行跑(比如JUnit),也就是单线程跑,那么多core的机器实际上只利用到了一个 core,造成了大量的CPU资源浪费。而如果另外修改算法代码,使得其并行化,虽然也可行,但是修改原先实现的算法代码是在太麻烦了。而实际上,不同的 算法,不同的参数,不同的数据,不同的run次数,本身之间就是独立的,所以test case与test case其实本身就可以并行运行。其实需要的只是调度的程序,能够去调度线程来跑这些test cases.

2)程序和数据的部署。 如果要在系里面多台机器上跑程序,那么程序的部署很繁琐。首先,需要把编译好的代码通过 SFTP/FTP拷贝到远程服务器上。另外,需要给不同的服务器,写不同的执行脚本。最后,还要通过SSH远程登录到每台服务器上,敲打命令,执行哪个运 行脚本。在程序执行期间,需要盯着各个SSH的窗口,等全部服务器都跑完了,然后在手工去每个机器上收集其执行结果,汇总。这个流程如果只做一次,不觉得 很麻烦。问题是,我们在测试和对比算法实验中,程序的代码在不断进化,修改,更新。每次更新,都需要如此做一遍流程,那么就实在太麻烦了。设想,如果要部 署到系里面十几台机器跑,那个工作量不得了。

根据这两个问题,于是本人利用了周末的一半时间,写了一个SimpleTestBed: http://code.google.com/p/simpletestbed/ 。 这个Test Bed工具,要解决的就是上述两个问题。它分两个部分,一个是服务器端,一个是客户端。服务器端要做的事情,就是把程序拷贝到每个服务器上,启动,然后就 不用管了。客户端这块,用户需要做的就是为自己的算法创建TestCase。TestCase在SimpleTestBed是一个interface,用 户实现之后,加入一个创建TestBed。接下来只需要执行TestBed的execute方法。SimpleTestBed会自动把加入的 TestCase分发到远程服务器上,创建多线程,执行,然后返回结果。

下面就是一个例子,在Google Code网站上可以看到完整代码 。

TestCase fiTestCase = new FibonacciTestCase(20);
TestCase rmTestCase = new RandomMeanTestCase(100, 200, 10);
TestBed testBed = new RemoteTestBed("firefly_config.txt");
testBed.addTestCase(fiTestCase);
testBed.addTestCase(rmTestCase);
double[] results = testBed.execute();
for (int i=0; i

你可能感兴趣的:(学习和工作,算法与程序设计)