为什么这个 for 循环不能并行工作?

Why does this for loop not work in parallel?

我正在尝试 运行 在 linux 版本的 R 中并行执行一个函数。但是,我一直发现每次并行迭代 returns NULL 而不是函数的输出。我已将问题隔离到 for 循环。

这是一个简化版本:

library(parallel)

rows <- seq(1,9,1)

for_test <- function(i){
  for (s in 1:3){
    print(i*s) 
  }
}

cls <- makeCluster(length(rows), type = 'FORK')

parLapply(cls, rows, for_test)

stopCluster(cls)

此 returns NULL 用于九次迭代中的每一次迭代,但将 for_test 函数更改为:

for_test <- function(i){
  s <- 2
  print(i*s)
}

returns i*s 而不是 NULL 的结果。我之前有 运行 for parallel 循环,但似乎无法弄清楚为什么它在这种情况下不起作用。谁能指出我哪里出错了?

首先:循环并行,我们只是看不到print。 returned NULL 不是 print 函数的结果,它是来自并行调用的函数 return 值的列表。收集值并 return 而不是 print。打印到外部文件也可以,但我建议先从普通方式开始,因为 parLapply 以方便的方式整理 return 值。

作为如何使用 return 值的示例,请尝试以下操作:

library(parallel)

rows <- seq(1,9,1)

for_test <- function(i){
  txt <- NULL
  for (s in 1:3){
    txt <- rbind(txt, c(i, s, i*s))
  }
  txt
}

cls <- makeCluster(length(rows))
parLapply(cls, rows, for_test)
stopCluster(cls)

解释:

在 OP 的第一个示例中 printfor loop 中,而在第二个版本中它是最后一个语句。 print return 是一个值,而 for()return 是 NULL.

演示:

> x <- print(2)
[1] 2
> x
[1] 2
> 
> x <- for (i in 1:2) print(2 * i)
[1] 2
[1] 4
> x
NULL
>