gpt4 book ai didi

r - doParallel 和 foreach 无法并行化合并操作

转载 作者:行者123 更新时间:2023-12-01 00:57:51 25 4
gpt4 key购买 nike

我正在尝试合并一个大 data.frame用一个小的,并并行计算。下面的代码完美运行,最大化了我机器的所有内核:

len <- 2000000
set.seed(666)
dat = paste(sample(letters, len, rep = T), sample(0:9, len, rep = T), sample(letters, len, rep = T), sep = '') # create a vector of strings that are 3-long
head(dat)
set.seed(777)
num <- sample(0:9, len, replace = T)
bigDF <- data.frame(dat = dat, num = num)
smallDF <- data.frame(num = 0:9, caps = toupper(letters[1:10]))
startP <- 1
chunk <- 10000
nodes <- detectCores()
cl <- makeCluster(nodes)
registerDoParallel(cl)
mergedList <- foreach(i = 0:(len/chunk - 1)) %dopar% {
tmpDF = bigDF[(startP + i * chunk):(startP - 1 + (i + 1) * chunk), ]
merge(tmpDF, smallDF, by = 'num', all.x = T)
}
stopCluster(cl)

一旦我改变矢量 dat要包含长度为 5 的字符串,并行性会崩溃,尽管没有错误或警告,但只有 1 个核心对计算有贡献:
len <- 2000000
set.seed(666)
dat = paste(sample(letters, len, rep = T), sample(0:9, len, rep = T), sample(letters, len, rep = T), sample(letters, len, rep = T), sample(letters, len, rep = T), sample(letters, len, rep = T), sep = '') # create a vector of strings that are 6-long
head(dat)
set.seed(777)
num <- sample(0:9, len, replace = T)
bigDF <- data.frame(dat = dat, num = num)
smallDF <- data.frame(num = 0:9, caps = toupper(letters[1:10]))
startP <- 1
chunk <- 10000
nodes <- detectCores()
cl <- makeCluster(nodes)
registerDoParallel(cl)
mergedList <- foreach(i = 0:(len/chunk - 1)) %dopar% {
tmpDF = bigDF[(startP + i * chunk):(startP - 1 + (i + 1) * chunk), ]
merge(tmpDF, smallDF, by = 'num', all.x = T)
}
stopCluster(cl)

为什么会出现这种不一致,以及如何解决它?在特定示例中,如果一个索引 dat代码工作的整数。但索引并不是在所有情况下的答案。为什么字符串的长度对使用的内核数量很重要?

最佳答案

我相信不同之处在于,在第一种情况下,“bigDF”的第一列是一个有 6,760 个级别的因子,而在第二种情况下,它有 1,983,234 个级别。拥有大量级别会导致许多性能问题。当我用 stringsAsFactors=FALSE 创建“bigDF”时,性能要好得多。

bigDF <- data.frame(dat=dat, num=num, stringsAsFactors=FALSE)

我还使用了 itertools 包中的“isplitRows”函数来避免将所有“bigDF”发送给每个工作人员:
library(itertools)
mergedList <- foreach(splitDF=isplitRows(bigDF, chunkSize=chunk)) %dopar% {
merge(splitDF, smallDF, by = 'num', all.x = T)
}

在我运行 R 3.1.1 的 6 核 Linux 机器上,您的第二个示例运行了大约 332 秒。当我使用 stringsAsFactors=FALSE ,它在大约 50 秒内运行。当我还使用 isplitRows 时,时间下降到 5.5 秒,或者比第二个示例快 60 倍。

关于r - doParallel 和 foreach 无法并行化合并操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26062110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com