Rom*_*rik 6 parallel-processing r snowfall
我有一个data.frame的单元格,值和坐标.它驻留在全球环境中.
> head(cont.values)
cell value x y
1 11117 NA -34 322
2 11118 NA -30 322
3 11119 NA -26 322
4 11120 NA -22 322
5 11121 NA -18 322
6 11122 NA -14 322
Run Code Online (Sandbox Code Playgroud)
因为我的自定义函数花了将近一秒来计算单个单元格(我需要计算数万个单元格),我不想复制已经有值的单元格的计算.以下解决方案试图避免这种情况.每个单元格可以独立计算,尖叫为并行执行.
我的函数实际上做的是检查是否有指定单元格编号的值,如果它是NA,则计算它并将其插入代替NA.
我可以使用apply函数系列来运行我的魔术函数(结果是value相应的cell),从内部apply,我可以读写cont.values没有问题(它在全局环境中).
现在,我想并行运行(使用snowfall),我无法从单个核心读取或写入此变量.
问题:在并行执行函数时,从工作者(核心)内部驻留在全局环境中的动态变量可以读取/写入什么解决方案.这样做有更好的方法吗?
工作人员查询值的中央存储模式是在CRAN 上的rrredis包中实现的。这个想法是,Redis 服务器维护键值对的存储(重新实现的全局数据框架)。工作人员查询服务器以查看该值是否已计算(redisGet),如果没有计算并存储它(redisSet),以便其他工作人员可以重复使用它。Workers可以是R脚本,因此很容易扩展劳动力。这是一个非常好的替代并行范例。这是一个使用“记忆”每个结果概念的示例。我们有一个很慢的函数(休眠一秒钟)
fun <- function(x) { Sys.sleep(1); x }
Run Code Online (Sandbox Code Playgroud)
我们编写一个“memoizer”,它返回一个变体,fun首先检查是否x已经计算出 的值,如果是,则使用该值
memoize <-
function(FUN)
{
force(FUN) # circumvent lazy evaluation
require(rredis)
redisConnect()
function(x)
{
key <- as.character(x)
val <- redisGet(key)
if (is.null(val)) {
val <- FUN(x)
redisSet(key, val)
}
val
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们记住我们的函数
funmem <- memoize(fun)
Run Code Online (Sandbox Code Playgroud)
去
> system.time(res <- funmem(10)); res
user system elapsed
0.003 0.000 1.082
[1] 10
> system.time(res <- funmem(10)); res
user system elapsed
0.001 0.001 0.040
[1] 10
Run Code Online (Sandbox Code Playgroud)
这确实需要一个在 R 之外运行的 Redis 服务器,但安装起来非常容易;请参阅 rrredis 软件包附带的文档。
R 内并行版本可能是
library(snow)
cl <- makeCluster(c("localhost","localhost"), type = "SOCK")
clusterEvalQ(cl, { require(rredis); redisConnect() })
tasks <- sample(1:5, 100, TRUE)
system.time(res <- parSapply(cl, tasks, funmem))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2841 次 |
| 最近记录: |