为什么以下for循环在R中使用我的计算机中的所有内核?

问题描述 投票:0回答:1

我有以下未明确启用并行化的R代码:

matrix <- matrix(rnorm(1000^2), ncol = 1000)
vec <- rnorm(1000)

for (i in 1:10000){
  a <- sum(matrix%*%vec)
}

当执行for循环时,我在系统监视器中注意到所有内核都以100%的利用率被使用。据我了解,R中的for循环始终是串行的。我确实注意到一个大型矩阵乘法只利用了一个内核,所以我不认为并行发生在矩阵乘法中。

这里更大的问题是,我编写了一个MCMC采样器,需要作为马尔可夫链来串行运行,但是当我运行采样器时,我看到所有内核都在使用。上面的代码只是一个最小的工作示例。我是否应该担心MCMC采样器不能以串行方式正常运行(即作为马尔可夫链)?

我在rocker / tidyverse:3.5.2 Docker容器内部使用R 3.5.2,而我的本地操作系统是Ubunutu 18.04。

感谢您的帮助!

这是我的会话信息:

R version 3.5.2 (2018-12-20)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 9 (stretch)

Matrix products: default
BLAS: /usr/lib/openblas-base/libblas.so.3
LAPACK: /usr/lib/libopenblasp-r0.2.19.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
 [6] LC_MESSAGES=C              LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_3.5.2 tools_3.5.2    yaml_2.2.0   
r for-loop parallel-processing blas markov-chains
1个回答
0
投票

感谢所有有用的评论。看起来BLAS使用多个线程进行矩阵乘法,默认情况下,它使用全部12。

有趣的是,当通过RhpcBLASctl::blas_set_num_threads(1)减少BLAS线程数时,总的计算时间减少了。对于具有12个逻辑处理器的计算机,请参见下面的结果:

RhpcBLASctl::blas_get_num_procs()
RhpcBLASctl::blas_set_num_threads(12)

matrix <- matrix(rnorm(1000^2), ncol = 1000)
vec <- rnorm(1000)

system.time(
for (i in 1:2000){
  matrix1 <- matrix + 1
  a <- sum(matrix1%*%vec)
}
)

RhpcBLASctl::blas_set_num_threads(1)
matrix <- matrix(rnorm(1000^2), ncol = 1000)
vec <- rnorm(1000)
system.time(
  for (i in 1:2000){
    matrix <- matrix + 1
    a <- sum(matrix1%*%vec)
  }
)

您将看到它实际上只用一个线程运行得更快(可能是由于数据传输开销?)。对于我的MCMC采样器,我将线程数设置为1,然后利用并行处理实际上会提高计算时间的其他内核(即并行运行多个链)。

© www.soinside.com 2019 - 2024. All rights reserved.