一直以来,总觉得并行计算是种很高深的技术,需要系统性的学习才能掌握。直到最近工作中进行大量循环计算,动辄十几个小时,实在是被整崩溃了,于是百度了一下,惊喜的发现R有很傻瓜的并行计算用法,完全满足基本的计算需求,这里简单记录一下。

  R语言的并行可以用parallel包,这个包是自带的,不用下载,直接library即可。它本质上相当于打开多个R控制台,然后将任务拆分后让这些控制台计算,等各部分计算完成后再合在一起呈现出来。

  完成一次并行计算需要的函数主要有:makeCluster、clusterExport、clusterEvalQ、clusterApply、parLapply、parSapply、parApply等。

  makeCluster(spec, type, ...)用于创建并行集合。参数spec可以理解为线程数,或并行计算“打开R控制台”的数量;参数type默认值为"PSOCK",是一种组织并行计算的底层结构,这个参数还可以选"FORK"。

  clusterEvalQ(cl = NULL, expr)用于在各线程中运行一些表达式,通常是用于加载各种包。参数cl表示要调用的并行集合(即makeCluster函数的运行结果);参数expr表示表达式。

  clusterExport(cl = NULL, varlist, envir = .GlobalEnv) 用于导入需要的变量。参数cl表示要调用的并行集合(即makeCluster函数的运行结果);参数varlist表示要导入的变量名称集合,相当于打开多个R控制台后在每个控制台中导入这些变量;参数envir,表示上述变量的来源,默认值.GlobalEnv表示变量从当前全局环境中导入。

  clusterApply、parLapply、parSapply、parApply等函数用于并行计算,用法类似apply函数族,只不过参数中要额外加入调用的并行集合cl。

  下面举一个简单的例子,使用quantmod包的getSymbols函数下载股票“600030.ss”和“000001.sz”的收盘价并输出最大值:

library(parallel)
## 构建变量
src <- "yahoo"
codes <- c("600030.SS", "000001.SZ")
## 构建函数,提取数据并计算最大值
FUN <- function(x){
  setSymbolLookup(XXX =list(name = x, src = src))
  getSymbols("XXX")
  res <- max(XXX[, paste0(x, '.Close')])
  return(res)
}
## 构建线程数为2的并行集合
cl = makeCluster(2)
## 函数FUN中需要src, 导入变量src
clusterExport(cl, varlist = 'src')
## 加载使用的包quantmod
clusterEvalQ(cl, expr = library(quantmod))
## 计算
res <- clusterApply(cl = cl, x = codes, fun = FUN)
## 输出结果
res


> res
[[1]]
[1] 37.82

[[2]]
[1] 17.22

  计算结果显示两只股票的最高收盘价格分别是37.82和17.22。

  parallel包的基本用法就介绍完了,它的计算使用了类“apply”函数的计算方式,如果想用循环,可以尝试foreach包。