什么时候我需要使用sfExport (R降雪包)



我使用snow进行并行计算。我总是只在一台机器上使用多个cpu(>20核)。我正在处理大量数据(>20gb)。sfExport()需要很长时间

当我在笔记本电脑上运行测试代码并检查CPU使用情况时,它有时也可以在没有sfExport()的情况下工作。

我代码的某些部分是嵌套的sfLapply()函数。如:

func2 <- function(c,d, ...) {      
  result <- 
    list(x = c+d,
         y = ..,
         ...
         )
  return(result)
}
func1 <- function(x, a, b, c, ...) {
  library(snowfall)
  d <- a+b
  result <- sfLapply(as.list(b$row), func2, c, d, ...)
  return(result)
}
result <- sfLapply(as.list(data.table$row), func1, a, b, c, ..)

什么时候需要导出数据到所有cpu ?

感谢并致以最良好的问候尼科

如果您要将一个20gb的对象导出到所有集群工作器,这将花费大量时间和使用大量内存。每个worker都将收到该20gb对象的自己的副本,因此您可能必须减少worker的数量以减少总内存使用量,否则您的机器可能会开始抖动,您的程序可能最终会死亡。在这种情况下,使用更少的工人可能会运行得更快。当然,如果你的机器有512gb的RAM,使用20个worker可能没问题,尽管将该对象发送给所有worker仍然需要很长时间。

如果每个worker需要一个特定的数据帧或矩阵来执行worker函数,那么导出它可能是正确的事情。如果每个worker只需要对象的一部分,那么您应该将其拆分,只发送每个worker需要的部分。关键是要准确地确定worker函数需要什么数据,并且只发送需要的数据。

如果一个对象似乎神奇地出现在worker上,即使你没有导出它,你可能在函数闭包中捕获了该对象。下面是一个例子:

library (snowfall)
sfInit (parallel=TRUE , cpus=4)
fun <- function() {
  x <- 100
  worker <- function(n) x * n
  sfLapply(1:1000, worker)
}
r <- fun()

这工作得很好,但是变量"x"是如何发送到集群工作器的并不明显。答案是,当sfLapply将任务发送给worker时,"x"与"worker"函数一起序列化,因为"worker"是在函数"fun"中定义的。在这种情况下,通过sfExport将"x"导出给工人是浪费时间。还需要注意的是,虽然这种技术在sfLapply中工作得很好,但在sfClusterApply和sfClusterApplyLB等不像sfLapply那样执行任务分块的函数中却不能很好地工作,尽管这只是在"x"非常大时才会出现问题。

我不会在这个主题上进行更多的细节讨论,只是说当你的工作函数在另一个函数中定义时,你应该非常小心。

相关内容

  • 没有找到相关文章

最新更新