【发布时间】:2016-10-11 13:56:27
【问题描述】:
我在分别具有 4 个和 8 个物理内核和逻辑内核的 PC (OS Linux) 上运行以下代码(从 doParallel's Vignettes 中提取)。
使用iter=1e+6 或更少的代码运行代码,一切都很好,我可以从 CPU 使用情况中看到所有内核都用于此计算。然而,随着迭代次数的增加(例如iter=4e+6),并行计算似乎在这种情况下不起作用。当我还监控 CPU 使用率时,只有一个核心参与计算(100% 使用率)。
示例 1
require("doParallel")
require("foreach")
registerDoParallel(cores=8)
x <- iris[which(iris[,5] != "setosa"), c(1,5)]
iter=4e+6
ptime <- system.time({
r <- foreach(i=1:iter, .combine=rbind) %dopar% {
ind <- sample(100, 100, replace=TRUE)
result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit))
coefficients(result1)
}
})[3]
您知道可能是什么原因吗?记忆可能是原因吗?
我四处搜索,发现 THIS 与我的问题相关,但关键是我没有遇到任何错误,并且 OP 似乎通过在 foreach 循环中提供必要的包来提出解决方案。但可以看出,我的循环中没有使用任何包。
更新1
我的问题还没有解决。根据我的实验,我不认为记忆可能是原因。我在运行以下简单并行(在所有 8 个逻辑内核上)迭代的系统上有 8GB 内存:
示例2
require("doParallel")
require("foreach")
registerDoParallel(cores=8)
iter=4e+6
ptime <- system.time({
r <- foreach(i=1:iter, .combine=rbind) %dopar% {
i
}
})[3]
我运行这段代码没有问题,但是当我监控 CPU 使用率时,只有一个核心(共 8 个)是 100%。
更新2
至于 Example2,@SteveWeston(感谢您指出这一点)表示(在 cmets 中):“您更新中的示例遇到了小任务。只有大师有任何实际工作to do,包括发送任务和处理结果。这与原始示例的问题根本不同,原始示例确实在较少次数的迭代中使用了多个内核。"
但是,Example1 仍未解决。当我运行它并使用htop 监控进程时,更详细的情况如下:
让我们将所有 8 个创建的进程命名为 p1 到 p8。 p1 的状态(htop 中的 S 列)是 R,这意味着它正在运行并且保持不变。然而,对于p2 到p8,几分钟后,状态变为D(即不间断睡眠),几分钟后,再次变为Z(即终止但未被其父级接收) .你知道为什么会这样吗?
【问题讨论】:
-
您是否尝试过显式创建和注册集群?例如
cl <- makePSOCKcluster(8); registerDoParallel(cl)? -
即使
iter=15e+6?您能否评论一下您的硬件规格(CPU 和内存)以及运行代码的操作系统类型? -
是的,它可能确实与内存或计算资源有关。那么你真的需要那么多迭代吗?如果是这样,您是否可以通过将其分成具有较少迭代的步骤然后组合(可能是平均)结果来获得相同的结果?我不确定您的用例是什么,但对于机器学习,您通常可以将模型进度保存到存储内存(即检查点)中,这样您就可以将大型神经网络和其他模型的训练分成多个会话。
-
我让它在 Windows 上运行全部 8 个(在 10-15 秒后自行排序),I7 4910 逐字运行您的上述代码。
-
您的更新中的示例遇到了小任务。只有master有真正的工作要做,包括发送任务和处理结果。这与在少量迭代中使用多个内核的原始示例的问题根本不同。
标签: r parallel-processing parallel-foreach doparallel