为什么以下 for-loop 在 R 中使用了我机器中的所有内核?
Why does the following for-loop utilize all of the cores in my machine in R?
我有以下未明确启用并行化的 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,我的本地 OS 是 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
感谢所有有用的评论。貌似是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,然后利用并行处理实际上会缩短计算时间的其他内核(即 运行 多个并行链)。
我有以下未明确启用并行化的 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,我的本地 OS 是 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
感谢所有有用的评论。貌似是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,然后利用并行处理实际上会缩短计算时间的其他内核(即 运行 多个并行链)。