R的并行运算

R作为主要流行的统计分析软件之一,其处理数据一般都是单线程的。随着数据量的增大,R运行的时间会大大增加;为了充分发挥计算机的性能和进一步提升R运行速度,使用并行运算不失为一种有效的手段。

简单的说R的并行化计算其实没有改变其整个并行环境,而是先启动N个附属进程,然后将数据分割成N块在N个核上进行运行,等待附属进程结束返回结果。与单线程运算相比,会大大节省运算时间

parallel

R内置了parallel包(R version > 2.14),强化了R的并行计算能力。parallel包的思路和lapply函数很相似,都是将输入数据分割、计算、整合结果。只不过并行计算是用到了不同的cpu内核来运算。两个核心的函数为mclapplyparlapply

  1. ## lapply
  2. system.time({
  3. res <- lapply(1:5000000, function(x) x+1);
  4. });
  5. user system elapsed
  6. 21.42 1.74 25.70
  7. ## parlapply
  8. # load parallel
  9. library(parallel)
  10. # check numrber of cores
  11. clnum<-detectCores()
  12. #设置参与并行的CPU核数目
  13. cl <- makeCluster(getOption("cl.cores", clnum));
  14. #运行
  15. system.time({
  16. res <- parLapply(cl, 1:5000000, function(x) x + 1)
  17. });
  18. user system elapsed
  19. 6.54 0.34 19.95
  20. #关闭并行计算
  21. stopCluster(cl);
  22. ## mclapply ==> mclapply适用于类Unix系统的操作
  23. mc <- getOption("mc.cores", 3)
  24. system.time({
  25. res <- mclapply(1:5000000, function(x){x+1}, mc.cores = mc);
  26. });
  27. user system elapsed
  28. 6.657 0.500 7.181

furrr

furrrfuturepurrr包的结合,提供了一系列的并行操作适用于*map家族函数

  1. library(furrr)
  2. library(tictoc)
  3. # This should take 6 seconds in total running sequentially
  4. plan(sequential)
  5. tic()
  6. nothingness <- future_map(c(2, 2, 2), ~Sys.sleep(.x))
  7. toc()
  8. #> 6.08 sec elapsed
  9. # This should take ~2 seconds running in parallel, with a little overhead
  10. plan(multiprocess)
  11. tic()
  12. nothingness <- future_map(c(2, 2, 2), ~Sys.sleep(.x))
  13. toc()
  14. #> 2.212 sec elapsed

parallel相比更喜欢furrr的傻瓜式操作,且其与其他R包的交互使用更为方便。

其他

其他一些并行相关的R包:
future : 强大的分布式处理并行包
future.apply : 基于future包开发的*apply家族函数并行包