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

标签 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?

谢谢和最好的问候 妮可

最佳答案

如果您要将 20 GB 的对象导出到所有集群工作程序,那将花费大量时间并使用大量内存。每个工作人员都会收到自己的 20 GB 对象副本,因此您可能必须减少工作人员的数量以减少总内存使用量,否则您的机器可能会开始抖动并且您的程序最终可能会死掉。在这种情况下,使用更少的 worker 可能会跑得更快。当然,如果您的机器有 512 GB 的 RAM,使用 20 个 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”导出给 worker 是浪费时间。另请注意,虽然此技术适用于 sfLapply,但它不适用于 sfClusterApply 和 sfClusterApplyLB 等函数,它们不像 sfLapply 那样执行任务分块,尽管这只是在“x”非常大时才会出现的问题。

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

关于r - 什么时候需要使用 sfExport(R Snowfall 包),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827737/

相关文章:

python - 如何从并行进程中运行的函数中检索值?

r - 如何设置集群从节点(在Windows上)

r - Snow结束后是否需要移除导出的变量

R - 使用 reshape() 将数据帧转换为两列矩阵

r - 根据 ID 选择数据行

matlab - 为什么矩阵乘法在 7 核工作站上比在我的笔记本电脑上运行得慢?

c# - 问题与 Task.WhenAll 并行调用 Azure 移动客户端

r - Windows 集群上的并行 R

r - as.Date 不保留 R 中的小时和分钟信息

r - 将价格数据聚合到 R data.table 中的不同时间范围