виньетка 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
sa 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, сколько пакетов он предоставляет и все хорошо документировано.Я надеюсь, что это поможет вам в ваших будущих параллельных вычислениях.