为什么这个并行计算代码只使用1个CPU?

Har*_*dev 5 r parallel-foreach doparallel

我正在使用foreachparallel库来执行并行计算,但由于某种原因,在运行时,它一次仅使用 1 个 CPU(我使用“top”(Linux 终端上的 Bash)进行查找。

服务器有48核,我尝试过:

  • 使用 24、12 或 5 核
  • 示例代码(如下)
  • 在 Windows 中,出现此类任务,但它们不使用任何 CPU
list.of.packages <- c("foreach", "doParallel")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if (length(new.packages)) install.packages(new.packages)

library(foreach)
library(doParallel)

no_cores <- detectCores() / 2 # 24 cores
cl<-makeCluster(no_cores)
registerDoParallel(cl)

df.a = data.frame(str = cbind(paste('name',seq(1:60000))), int = rnorm(60000))
df.b = data.frame(str = sample(df.a[, 1]))
df.b$int = NA

foreach(row.a = 1:length(df.a$str),
        .combine = rbind,
        .verbose = T)  %dopar% {
          row.b = grep(pattern = df.a$str[row.a], x = df.b$str)
          df.b$int[row.b] = df.a$int[row.a]
          df.b
        }
stopCluster(cl)

Run Code Online (Sandbox Code Playgroud)

我希望这段代码使用多个 CPU(与定义的一样多),但它实际上使用 1 个。

Chr*_*ris 3

跑去foreach(..., verbose = TRUE)了解发生了什么。稍微更改了正在运行的代码,以便更好地识别并行代码何时运行。

library(foreach)
library(doParallel)

no_cores <- detectCores() / 2 # 24 cores
cl<-makeCluster(no_cores)
registerDoParallel(cl)

base = 2

out <- foreach(exponent = 2:400,
        .combine = sum, .verbose = TRUE)  %dopar%
  runif(1000000)
Run Code Online (Sandbox Code Playgroud)

第一段:

# discovered package(s):  
# no variables are automatically exported
# explicitly exporting package(s):
# numValues: 3999, numResults: 0, stopped: TRUE
Run Code Online (Sandbox Code Playgroud)

这个设置不是并行的——这是你的主人设置你的孩子。这需要很长时间2:40000000,这可能是您停止的地方,并且您只会看到一个核心正在使用。

# numValues: 79, numResults: 0, stopped: TRUE
# got results for task n
Run Code Online (Sandbox Code Playgroud)

当您等待打印时,该计算应该是并行的。在 Windows 上,我看到 4 个核心正在工作来计算每个runif.

# calling combine function
# evaluating call object to combine results:
#   fun(accum, result.n)
Run Code Online (Sandbox Code Playgroud)

这针对具有不同 n 值的每个工作人员运行。这是您的组合函数,也不是并行的。

我认为您的代码挂在设置部分上,而您仅观察操作的串行部分。如果没有,我会观察正在发生的事情并verbose = TRUE寻找更多线索。

我不知道你的主要问题是如何设置的,但你的示例并不是如何设置并行化的好例子 - 你正在使用数百万个工作人员来执行非常小的任务,因此每个工作人员的串行开销成本非常高。如果您可以向每个工作人员发送更大的块,您将会看到性能的提高。