【问题标题】:R: Speeding up Code, multicoreR:加速代码,多核
【发布时间】:2014-09-02 16:36:35
【问题描述】:

我的 R 代码的性能有问题。 我的代码很慢。我必须遍历一个包含 3000 个元素的向量。在每个循环中,我都会调用许多函数。 我首先尝试了并行化,但它不起作用。在每一步中,我都需要前面步骤的结果。 现在我有了一个想法:我将向量分成 3 块,每块 1000 个元素。并自行计算每一件。在第 1 和第 2 部分的第一个元素上,我会遇到问题,但我可以处理它。 我想通过一个单独的 CPU-Core 计算这 3 个部分中的每一个。 实际上我可以制作 3 个 .R-Files 并启动 3 个 R-Sessions (=3 Cores) 并计算它。 但我想在一个文件中完成。我想定义,我的第一个循环将由 Core 1 计算,而其他循环将由其他 Cores 计算。

有可能吗? 谢谢。

这是一个简单的例子。它描述了我的问题。

#Situation now  
vec3000 <- rnorm(3000)
result3000 <- rep(NA, length(vec3000))
for (i in 1 : 3000){
    if (i == 1){
        result3000[i] <- vec3000[i]
    }else{
        result3000[i] <- result3000[i - 1] + vec3000[i]
    }
}

#New Situation
vec1000_1 <- vec3000[1:1000]
vec1000_2 <- vec3000[1001:2000]
vec1000_3 <- vec3000[2001:3000]
result1000_1 <- rep(NA, 1000)
result1000_2 <- rep(NA, 1000)
result1000_3 <- rep(NA, 1000)

#Calculated by Core 1
for (i in 1 : 1000){
    if (i == 1){
        result1000_1[i] <- vec1000_1[i]
    }else{
        result1000_1[i] <- result1000_1[i - 1] + vec1000_1[i]
    }
}

#Calculated by Core 2
for (i in 1 : 1000){
    if (i == 1){
        result1000_2[i] <- vec1000_2[i]
    }else{
        result1000_2[i] <- result1000_2[i - 1] + vec1000_2[i]
    }
}   

#Calculated by Core 3
for (i in 1 : 1000){
    if (i == 1){
        result1000_3[i] <- vec1000_3[i]
    }else{
        result1000_3[i] <- result1000_3[i - 1] + vec1000_3[i]
    }
}

【问题讨论】:

  • 请提供一个可重复的最小示例,以便其他人可以更轻松地提供帮助。您将获得更好/更快的答案,更适合您的特定问题。
  • 是的,这是可能的:请参阅parallels 包中的一个示例。这是否是减少您的处理时间的最佳方法是未知的,因为您没有发布您的功能或您想要的输出。可能有更好的方法来计算您想要的结果。
  • result1000_1 = cumsum(vec1000_1) 会很快,无需浪费时间并行处理低效的代码。
  • 你试过并行运行这个吗?
  • 我知道我可以在这里使用cumsum。但这是一个例子。我的问题更复杂。我没有并行地尝试这个例子。但是我的示例会产生错误。 :{ 中的错误:任务 1 失败 -“'S4' 类型的对象......。

标签: r parallel-processing multicore


【解决方案1】:

这是一个使用 foreach 包并行操作向量块的示例:

library(doParallel)
library(itertools)
nworkers <- 3
cl <- makePSOCKcluster(nworkers)
registerDoParallel(cl)
vec3000 <- rnorm(3000) # dummy input

# This computes "resvecs" which is a list of "nworkers" vectors
resvecs <- foreach(vec=isplitVector(vec3000, chunks=nworkers)) %dopar% {
    result <- double(length=length(vec))
    for (i in seq_along(result)) {
        if (i == 1) {
            result[i] <- vec[i]
        } else {
            result[i] <- result[i - 1] + vec[i]
        }
    }
    result
}

这使用了 itertools 包中的“isplitVector”函数将“vec3000”分成三个块,以利用三个内核。您可以更改“nworkers”的值来控制使用的核心数。

请注意,我使用了 doParallel 后端,因此该示例可以在 Windows、Mac OS X 和 Linux 上运行。

【讨论】:

  • 谢谢。您的示例非常完美。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 2022-11-07
  • 2017-04-13
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多