检测/确保在多核中使用多个内核

时间:2012-02-29 07:48:30

标签: r multicore

我使用多核R包中的并行和收集函数来并行化简单的矩阵乘法代码。答案是正确的,但并行版本似乎与串行版本的时间相同。

我怀疑它只在一个核心上运行(而不是我机器上的8个核心!)。有没有办法检测到这种情况并确保使用超过1个核心?

这是我的代码:

library("multicore")

A = read.table("matrixA.txt")
B = read.table("matrixB.txt")
A = as.matrix(A)
B = as.matrix(B)
rows = dim(A)[1]
columns = dim(B)[2] 

C <- mcparallel(A%*%B)
C <- collect(list(C))
C <- as.matrix(C[[1]])

write.table(C,"matrixC_mc.txt",row.names=FALSE, col.names=FALSE)

2 个答案:

答案 0 :(得分:5)

自R 2.14.0以来所包含的detectCores()软件包的parallel功能可以实现您实际拥有多个内核所需的功能:

R> parallel::detectCores()
[1] 8
R> 

此外,mcparallel本身并不会将矩阵乘法转换为并行操作(因为这是一个“硬”问题,请参阅ScaLAPACK库)。但是你可以尝试一些简单的东西:

R> X <- 1:1e3
R> rbenchmark::benchmark(serial=sapply(X, function(x) log(sqrt(x))), 
+>                       parallel=mclapply(X, function(x) log(sqrt(x))), 
+>                       replications=500)
      test replications elapsed relative user.self sys.self user.child sys.child
2 parallel          500  12.018    10.96     0.000    10.59      0.952     15.07
1   serial          500   1.097     1.00     1.208     0.00      0.000      0.00
R>

因此,对于短向量,并行增益的简单操作(sqrt(log(x)))的500次复制。但生活从未如此简单:在较大的载体上,差异消失了:

R> X <- 1:1e5
R> rbenchmark::benchmark(serial=sapply(X, function(x) log(sqrt(x))),
+>                       parallel=mclapply(X, function(x) log(sqrt(x))), 
+>                       replications=10)
      test replications elapsed relative user.self sys.self user.child sys.child
2 parallel           10   2.030     1.00     0.476    0.272      1.952     1.112
1   serial           10   2.821     1.39     2.228    0.592      0.000     0.000
R> 

令人遗憾的是,并行计算很棘手,而且比将表达式粘贴到mcparallelparallel要困难得多。

答案 1 :(得分:4)

根据您使用的操作系统,只需检查您的处理器使用情况。当我使用并行处理时,我可以在top中清楚地看到我的所有六个处理器都被使用了。

关于您的代码示例,mcparallel(您不应该使用,根据手册使用parallel)只会使用该表达式生成一个新进程。因此,如果使用矩阵乘法生成一个新进程,则只使用一个核心。仅在多次调用parallel时,才会启动多个进程,并使用多个核心。也许如果你切割你的矩阵,在多个过程中运行它们,并在以后组合它们,你可以获得一些优势。你可以看看mclapply。但是并行线性代数可能更容易使用multicore包,而是使用支持并行处理的blas(线性代数库)版本。