Почему следующий цикл for использует все ядра моей машины в R? - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть следующий код R с явно не включенным распараллеливанием:

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

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

Когда я выполняю цикл for, я замечаю в системном мониторе, что все ядра используются на 100%.Насколько я понимаю, петли в R всегда последовательны.Я замечаю, что с одним большим матричным умножением используется только одно ядро, поэтому я не верю, что при умножении матрицы происходит распараллеливание.

Большая проблема в том, что я написал сэмплер MCMC.это должно быть запущено последовательно как цепь Маркова, но когда я запускаю сэмплер, я вижу, что все ядра используются.Приведенный выше код является лишь минимальным рабочим примером.Должен ли я быть обеспокоен тем, что сэмплер MCMC не работает должным образом в последовательном режиме (т. Е. Как цепочка Маркова)?

Я использую R 3.5.2 внутри рокера / тидиверса: 3.5.2 контейнер Docker и мойлокальная ОС - 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   

1 Ответ

2 голосов
/ 27 сентября 2019

Спасибо за все полезные комментарии.Похоже, что BLAS использует несколько потоков для умножения матриц, и по умолчанию использовались все 12.

Интересно, что при уменьшении числа потоков BLAS с помощью RhpcBLASctl::blas_set_num_threads(1) общее время вычислений уменьшается.Посмотрите результаты ниже для моей машины с 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, а затем использую другие ядра, где параллельная обработка фактически улучшит время вычислений (т. Е. Параллельное выполнение нескольких цепочек).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...