A_S*_*n73 26 parallel-processing r mclapply
我一直在使用R中并行技术的项目近期开工,并有我的程序使用Linux系统的工作mclapply从并行包.但是,我parLapply对Windows的理解遇到了障碍.
使用mclapply我可以设置核心数,迭代次数,并将其传递给我的工作区中的现有函数.
mclapply(1:8, function(z) adder(z, 100), mc.cores=4)
Run Code Online (Sandbox Code Playgroud)
我似乎无法在Windows中实现相同的功能parLapply.据我了解,我需要通过使用传递所有变量clusterExport()并将我想要应用的实际函数传递给参数.
这是正确的还是有类似于mclapply适用于Windows 的功能?
Ste*_*ton 29
美妙之mclapply处在于,工作进程都是在mclapply被调用时创建为主数据的克隆,因此您不必担心在每个集群工作者上重现您的环境.不幸的是,这在Windows上是不可能的.
使用时parLapply,通常需要执行以下附加步骤:
此外,当您完成后,最好使用关闭PSOCK群集stopCluster.
以下是您的示例的翻译parLapply:
library(parallel)
cl <- makePSOCKcluster(4)
setDefaultCluster(cl)
adder <- function(a, b) a + b
clusterExport(NULL, c('adder'))
parLapply(NULL, 1:8, function(z) adder(z, 100))
Run Code Online (Sandbox Code Playgroud)
如果您的adder函数需要一个包,那么在调用它之前,您必须在每个worker上加载该包parLapply.您可以通过clusterEvalQ以下方式轻松完成:
clusterEvalQ(NULL, library(MASS))
Run Code Online (Sandbox Code Playgroud)
注意第NULL一个参数clusterExport,clusterEval并parLapply指示它们应该使用通过注册的集群对象setDefaultCluster.如果您的程序mclapply在许多不同的函数中使用,那么这非常有用,这样您在转换程序时就不必将集群对象传递给需要它的每个函数parLapply.
当然,adder可以调用全局环境中调用其他函数等的其他函数.在这种情况下,您还必须导出它们并加载它们需要的任何包.另请注意,如果您导出的任何变量在程序过程中发生更改,则必须再次导出它们才能在群集工作程序上更新它们.同样,这不是必需的,mclapply因为无论何时调用它,它总是创建/克隆/分叉工作,这使得不必要.
mclapply 使用起来更简单,并且使用底层操作系统 fork() 功能来实现并行化。但是,由于 Windows 没有 fork(),因此它将运行标准 lapply - 无并行化。
parLapply 是一个不同的野兽。它将创建一个进程集群,这些进程甚至可以驻留在网络上的不同计算机上,并且它们通过 TCP/IP 进行通信,以便在彼此之间传递任务和结果。
您的代码中的问题是您没有意识到 parLapply 的第一个参数应该是“集群”对象。我能想到的使用 parLapply 在单台机器上运行的最简单的示例是这样的:
library(parallel)
# Spawn child processes using fork() on the local machine
cl <- makeForkCluster(getOption("cl.cores", 2))
# Use parLapply to calculate lengths of 1000 strings
text = rep("Hello, world!", 1000)
len = parLapply(cl, text, nchar)
# Kill child processes since they are no longer needed
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
将 parLapply 与上面使用 makeForkCluster 创建的集群一起使用在功能上等同于调用 mclapply。所以它也不适用于 Windows。:) 查看文档中使用 makeCluster 和 makePSOCKcluster 创建集群的其他方法,并了解哪种方法最适合您的要求。