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

时间:2014-05-23 11:14:47

标签: r parallel-processing snow snowfall

我正在使用降雪进行并行计算。我总是只有一台具有多个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?

谢谢和最诚挚的问候 尼科

1 个答案:

答案 0 :(得分:1)

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

如果每个工作人员都需要一个特定的数据框或矩阵来执行worker函数,那么导出它可能是正确的做法。如果每个工作者只需要对象的一部分,那么您应该将其拆分并仅发送每个工作人员所需的部分。关键是确切地确定工作者功能需要什么数据,并且只发送所需的数据。

如果某个对象神奇地出现在工作人员身上,即使您没有导出它,您可能会在函数闭包中捕获该对象。这是一个例子:

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

这很好用,但变量&#34; x&#34;并不是很明显。被发送给集群工作者。答案是&#34; x&#34;与&#34; worker&#34;一起序列化当sfLapply将任务发送给工人时起作用,因为&#34; worker&#34;在函数内部定义&#34; fun&#34;。这是浪费时间出口&#34; x&#34;在这种情况下通过sfExport给工人。另请注意,虽然这种技术适用于sfLapply,但它并不适用于sfClusterApply和sfClusterApplyLB这样的功能,它们不像sfLapply那样执行任务分块,尽管这只是一个问题,如果&# 34; X&#34;非常大。

我不会再详细讨论这个问题,只是说当你的工作函数在另一个函数中定义时你应该非常小心。