2014-05-23 30 views
1

我正在使用降雪进行并行计算。我总是只在一台机器上安装多个CPU(> 20个内核)。我正在处理大量数据(> 20GB)。 sfExport()需要很长时间。什么时候需要使用sfExport(R降雪包)

当我在我的笔记本电脑上运行我的测试代码并检查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

如果要导出一个20 GB的对象到所有群集的工人,这将需要大量的时间和使用大量的内存。每个工作人员都会收到自己的20 GB对象的副本,因此您可能不得不减少工作人员的数量以减少总内存使用量,否则您的计算机可能会发生抖动,并且程序最终可能会死亡。在这种情况下,使用较少的工人可能运行得更快。当然,如果你的机器有512GB的内存,使用20个工人可能会很好,但是将这个对象发送给所有的工人还需要很长时间。

如果每个工作人员都需要一个特定的数据框或矩阵来执行辅助功能,那么导出它可能是正确的。如果每个工作人员只需要部分对象,那么您应该将其分解并仅发送每个工作人员所需的部分。关键是确定工作人员功能需要哪些数据,并只发送所需的数据。

如果即使您没有导出对象,但是您可能会在函数闭包中捕获该对象。下面是一个例子:

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

这工作正常,但变量“x”如何发送给群集工作人员并不明显。答案是,当sfLapply将任务发送给工作人员时,“x”与“worker”函数一起序列化,因为“worker”在函数“fun”中定义。在这种情况下,通过sfExport将“x”输出给工人是浪费时间。还要注意,虽然这种技术适用于sfLapply,但它不适用于像sfClusterApply和sfClusterApplyLB这样的不像sfLapply那样执行任务组块的函数,尽管这只是一个问题,如果“x”非常大。

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

相关问题