星期二, 二月 07, 2012

使用snow包实现双核心并行计算


在数据挖掘和机器学习领域有许多的算法需要强大的计算能力,如果对大数据进行运算操作,那么其工作量之大使单个CPU核心难以承受负荷。目前的个人计算机已经具备有多个核心,如果采用并行计算将任务分解到多个核心上运行就能大大减少计算时间。进一步还可以将多台计算机组合成计算集群(Cluster)则能使之具备组合金刚般的运算能力。

目前已经有多个R语言扩展包专注于高性能运算,弥补了R本身单核心作业的弱点。其中snow(Simple Network of Workstations)是R语言中最流行的并行编程包于2003年推出,本文将尝试用snow来运算K均值聚类
我们先用单核心运算K均值聚类来看看花费的时间,用到的数据集是MASS包中的Boston数据,我们希望将其聚为4类,由于K均值聚类的算法是随机确定初始中心点,所以为了使之收敛到最优解上需要反复运算多次。此处nstart参数设置为100000,即为运算次数。
system.time({
  library(MASS)
  result <- kmeans(Boston,4,nstart=100000)
})
可看到单核心计算共耗费了61秒,再用本地计算机上用双核心构建集群进行比较。在安装和加载snow包后,首先用makeCluster函数构建本地计算集群,通讯方式使用socket,集群命名为cl。然后将运算所需的Boston数据分发到集群上。之后使用clusterApply函数将计算任务分配到两个核心上,其中第一个参数是集群名称,第二个参数表示每个核心分别计算5万次,第三个参数是一个匿名函数,规定了核心的计算任务。两个核心的计算结果分别存在results的list元素中。比较两个核心的结果取较优的一个,最后关闭集群。

install.packages('snow')
library(snow)
system.time({
  data(Boston)
  cl <- makeCluster(2,type='SOCK')
  clusterExport(cl,'Boston')
  results <- clusterApply(cl,rep(50000,2),function(nstart) kmean(Boston,4,nstart=nstart))
  i <- sapply(results,function(result) result$tot.withinss)
  result <- results[[which.min(i)]]
  stopCluster(cl)
})

从结果观察到本地双核心组成的计算集群只耗费了34秒即完成了运算。snow也可以用多台计算机构建集群,不过设置蛮复杂,笔者没有折腾成功。总而言之,snow是一种高级包,它不关注底层的线程之间的通讯,而着重于任务的执行易于使用,相对R的单核心弱点是很好的补充。

参考资料:
Parallel R
The Art of R Programming
http://www.sfu.ca/~sblay/R/snow.html
http://cran.r-project.org/web/packages/snow/snow.pdf

没有评论:

发表评论