代码之家  ›  专栏  ›  技术社区  ›  Pierre Cattin

R并行-簇内的簇

  •  1
  • Pierre Cattin  · 技术社区  · 8 年前

    我需要运行一个昂贵的算法320次。我可以很容易地将其并行化到4个集群上,每个集群运行80次迭代。我可以访问一台32核的机器,所以我想进一步并行处理这个问题。将80个迭代组并行化比较困难,但这是可能的。我的想法是在每个主集群上运行8个子集群,每个集群处理10次迭代。

    为了测试这个想法,我使用R中的并行包实现了下面的虚拟代码。我在4个内核上测试了它,结果很惊讶。

    正态变量发生器

    方法1:在2个集群上并行一次

    library(parallel)
    library(tictoc)
    N <- 6*10^8 # total number of observations to generate
    
    n.threads <- 2
    sample.sizes <- rep(round(N/n.threads, 0), n.threads) # Each cluster generates half of the sample
    tic()
    cl <- makeCluster(n.threads)
    list <- parLapply(cl, sample.sizes, rnorm)
    stopCluster(cl)
    v <- unlist(list)
    toc()
    rm(list, v); gc()
    

    36秒执行时间;50%CPU使用率

    方法二:先并行2个以上的簇,然后再将每个簇再并行到2个簇上

    library(parallel)
    library(tictoc)
    
    N <- 6*10^8 # total number of observations to generate
    
    rnorm.parallel <- function(N.inside){
      n.threads.inside <- 2
      sample.sizes <- rep(round(N.inside/n.threads.inside, 0), n.threads.inside)  # each sub thread generates 1*10^8 obs
      cl.inside <- makeCluster(n.threads.inside)
      list <- parLapply(cl.inside, sample.sizes, rnorm)
      stopCluster(cl.inside)
      v <- unlist(list)
      return(v)
    }
    
    n.threads <- 2
    sample.sizes <- rep(round(N/n.threads, 0), n.threads) # each main thread generates 2*10^8 obs
    tic()
    cl <- makeCluster(length(sample.sizes))
    clusterEvalQ(cl, library(parallel))
    list <- parLapply(cl, sample.sizes, rnorm.parallel)
    stopCluster(cl)
    v <- unlist(list)
    toc()
    rm(list, v); gc()
    

    42秒执行时间;100%CPU使用率

    我的结论是,虽然在集群中运行集群的技术是可行的,但是额外的开销会降低效率。有没有其他的方法可以帮助我?

    0 回复  |  直到 8 年前