我是R中并行计算的新手,并且想使用并行包来加快我的计算速度(这比下面的示例要复杂得多)。但是,与通常的lapply函数相比,使用mclapply函数时,计算所需的时间更长。
我在笔记本电脑上安装了一个新的Ubuntu 18.04.2 LTS,它具有7.7 GB内存和1.80GHz×4处理器的Intel®Core™i7-4500U CPU。我正在R Studio上运行R。
require(parallel)
a <- seq(0, 1, length.out = 110) #data
b <- seq(0, 1, length.out = 110)
c <- replicate(1000, sample(1:100,size=10), simplify=FALSE)
function_A <- function(i, j, k) { # some random function to examplify the problem
i+ j * pmax(i-k,0)
}
#running it with mclapply
ptm_mc <- proc.time()
output <- mclapply(1:NROW(c), function(o){
mclapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_mclapply <- proc.time() - ptm_mc
# running it with lapply
ptm_lapply <- proc.time()
output <- lapply(1:NROW(c), function(o){
lapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_lapply <- proc.time() - ptm_lapply
lapply的结果比mclapply的结果快很多:
> time_mclapply
user system elapsed
6.030 439.112 148.088
> time_lapply
user system elapsed
1.662 0.165 1.827
为什么会得到这个结果?是因为我的设置还是常见问题? 我怎样才能得到比实际结果更快的结果,所以整个过程会更快?
更新: 嵌套循环的其余两个组合的更新:
ptm_mc_OUT <- proc.time()
output <- mclapply(1:NROW(c), function(o){
lapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_mclapply_OUT <- proc.time() - ptm_mc_OUT
ptm_mc_IN <- proc.time()
output <- lapply(1:NROW(c), function(o){
mclapply(1:NROW(a),function(p) function_A(a[p], b, c[[o]]))})
time_mclapply_IN <- proc.time() - ptm_mc_IN
require(dplyr)
times <- rbind(time_mclapply,
time_lapply,
time_mclapply_OUT,
time_mclapply_IN) %>% data.frame()
times
这给了我们
>times
user.self sys.self elapsed user.child sys.child
time_mclapply 0.075 0.081 22.621 1.933 34.266
time_lapply 1.070 0.049 1.118 0.000 0.000
time_mclapply_OUT 0.064 0.077 0.884 2.539 34.587
time_mclapply_IN 1.329 31.843 37.426 5.108 28.879
在另一次运行中我得到了(所以运行时间似乎相差很大,是否有更好的显示方式?)
times_lapply
user.self sys.self elapsed user.child sys.child
time_mclapply 0.324 0.121 9.108 0.000 0.000
time_lapply 1.060 0.049 1.108 0.000 0.000
time_mclapply_OUT 0.211 0.092 1.155 10.791 19.632
time_mclapply_IN 1.221 22.196 27.089 5.130 23.032
答案 0 :(得分:1)
让N为您计算机的线程数。一些建议:
不应使用两个并行级别,因为将使用N ^ 2个线程。
您应该尝试在外部循环而不是内部循环中并行化(因为并行性的开销只会发生一次)。
您不应该使用所有线程(人们通常使用N-1或N / 2)。
使用N / 2(mc.cores = parallel::detectCores() / 2
)时,time_mclapply_OUT
的速度是time_lapply
的两倍。