виньетка forach/doParallel говорит (для кода, который намного меньше вашего):
Обратите внимание, что это не практическое использование doParallel. Это наша программа «Hello, world» для параллельных вычислений. Он проверяет, все ли установлено и настроено правильно, но не ожидайте, что он будет работать быстрее, чем последовательный цикл for, потому что это не так! sqrt выполняется слишком быстро, чтобы его можно было выполнять параллельно, даже при большом количестве итераций. При небольших задачах накладные расходы на планирование задачи и возврат результата могут превышать время выполнения самой задачи, что приводит к низкой производительности. Кроме того, в этом примере не используются векторные возможности sqrt, необходимые для получения достойной производительности. Это всего лишь тест и педагогический пример, а не эталон.
Так что может быть в характере вашей настройки, что это не быстрее.
Вместо этого попробуйте без распараллеливания, но с использованием векторизации:
q <- sapply(1:1e6, function(x) 1 + 1 )
Он делает то же самое, что и циклы вашего примера, и делается за секунду. А теперь попробуйте это (он делает то же самое в одно и то же время:
x <- rep(1, n=1e6)
r <- x + 1
Он мгновенно добавляет к 1e6 1
s 1
. (Сила векторизации...)
Комбинация foreach
с doParallel
по моему личному опыту намного медленнее, чем если использовать пакет биоинформатики BiocParallel
из репозитория Bioconda. (Я биоинформатик, и в биоинформатике у нас очень часто бывают сложные расчеты, поскольку нам нужно обрабатывать отдельные файлы данных размером в несколько гигабайт - и их много). Я попробовал вашу функцию с помощью BiocParallel
, и она использует все назначенные процессоры на 100% (проверено запуском htop
во время выполнения задания), все это заняло 17 секунд.
Конечно - с вашим легким примером это применимо:
накладные расходы на планирование задачи и возврат результата могут быть больше, чем время выполнения самой задачи
Во всяком случае, кажется, что он использует процессоры более тщательно, чем doParallel
. Так что используйте это, если вам нужно выполнить сложные вычислительные задачи. Вот код, как я это сделал:
# For bioconductor packages, the best is to install this:
install.packages("BiocManager")
# Then activate the installer
require(BiocManager)
# Now, with the `install()` function in this package, you can install
# conveniently Bioconductor packages like `BiocParallel`
install("BiocParallel")
# then, activate it
require(BiocParallel)
# initiate cores:
bpparam <- bpparam <- SnowParam(workers=4, type="SOCK") # 4 or take more CPUs
# prepare the function you want to parallelize
FUN <- function(x) { 1 + 1 }
# and now you can call the function using `bplapply()`
# the loop parallelizing function in BiocParallel.
s <- bplapply(1:1e6, FUN, BPPARAM=bpparam) # each value of 1:1e6 is given to
# FUN, note you have to pass the SOCK cluster (bpparam) for the
# parallelization
Для получения дополнительной информации перейдите к виньетке пакета BiocParallel. а>. Посмотрите на bioconductor, сколько пакетов он предоставляет, и все они хорошо задокументированы. Я надеюсь, что это поможет вам в ваших будущих параллельных вычислениях.
person
Gwang-Jin Kim
schedule
11.10.2018
future.apply
. Вы настраиваете его с помощьюlibrary(future.apply); plan(multiprocess(workers = 3))
, а затем можете выполнить свою функцию с помощью:future_sapply(X = 1:1e6, FUN = function(x) {1 + 1})
- person bschneidr   schedule 12.10.2018