Обнаружение / обеспечение использования нескольких ядер в многоядерных системах - PullRequest
3 голосов
/ 29 февраля 2012

Я использую параллельные и собираю функции из многоядерного пакета 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 ]

5 голосов
/ 29 февраля 2012

Функция detectCores() пакета parallel, включенного в R 2.14.0, делает то, что вам нужно, если у вас действительно несколько ядер:

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>

Таким образом, для 500 повторений простой операции (sqrt(log(x))) на коротких векторах параллельное усиление. Но жизнь никогда не бывает такой простой: на больших векторах разница исчезает:

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> 

Печальная новость заключается в том, что параллельные вычисления сложны и намного сложнее, чем просто вставить выражение в mcparallel или parallel.

4 голосов
/ 29 февраля 2012

В зависимости от того, какую ОС вы используете, просто проверьте использование вашего процессора.Когда я использую параллельную обработку, я ясно вижу в top, что используются все мои шесть процессоров.

Что касается вашего примера кода, mcparallel (который вы не должны использовать, используйте parallel в соответствии сруководство) просто порождает новый процесс с этим выражением.Поэтому, если вы породите один новый процесс с умножением матрицы, будет использовано только одно ядро.Только при многократном вызове parallel запускается несколько процессов и используются несколько ядер.Возможно, если вы порежете свои матрицы, запустите их в нескольких процессах и объедините их позже, вы можете получить некоторые преимущества.Вы можете посмотреть на mclapply для этого.Но параллельную линейную алгебру, возможно, проще сделать, используя не пакет multicore, а версию blas (библиотека линейной алгебры), которая поддерживает параллельную обработку.

...