现在的位置: 首页 > 综合 > 正文

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

2012年06月24日 ⁄ 综合 ⁄ 共 1942字 ⁄ 字号 评论关闭

最近在研究一个近似的优化算法。在做对比实验的时候,一共要跑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网站上可以看到完整代码 

里面创建了2个TestCase,一个是算Fibonacci数的。另外一个算random varaible的mean。FibonacciTestCase
类和RandomMeanTestCase

也可以在google
code里面看到。这里的每个TestCase都会执行20次。两个TestCase会分发到两台不同的远程服务器上执行。两台远程服务器的
hostname可以通过配置文件,firefly_config.txt, 来配置。现在这个配置文件格式很简单,每行一个server的host
name。

关于SimpleTestBed的实现细节,主要用到了Java里面反射机制,Reflection。于是,我可以在客户端执行的时候,让
TestCase自己把自己传输到服务器上,然后在通知服务器去执行。服务器端不需要预先做任何事情。这种反射机制,让程序和数据的远程部署变得异常简
单。我在Eclipse就可以完成所有的测试,不需要在使用到什么SFTP/FTP, putty等工具了。

http://blog.csdn.net/tangl_99/archive/2011/03/11/6241505.aspx

抱歉!评论已关闭.