#r #performance #parallel-processing #apply
#r #Производительность #параллельная обработка #применить
Вопрос:
Мне интересно, существует ли версия mapply()
, которая работает параллельно для Windows. parallel
Пакет имеет отличные возможности для распараллеливания apply
функций, но, похоже, в нем отсутствует опция Windows для mapply()
. parallel
Пакет имеет mcapply
функции для пользователей, не являющихся пользователями Windows (ie mcapply()
, mclapply()
mcmapply()
и т.д.), И parApply
функции для пользователей Windows (ie parApply()
, parLapply()
и т.д.). Однако parLapply()
их нет.
Есть ли эквивалент mcmapply()
для Windows?
Вот два списка:
list1 <- list(elem1 = 1:3, elem2 = 4:6, elem3 = 7:9)
list2 <- list(elem1 = 10:12, elem2 = 13:15, elem3 = 15:17)
Я хочу добавить их вместе;
(result <- mapply(FUN = function(x, y){
x y
}, list1, list2, SIMPLIFY = FALSE))
Как я могу воссоздать это параллельно для пользователей Windows?
Примечание: parApply
функции не являются заменяющими элементами, как mcapply
функции. Смотрите ссылку для получения хорошей документации о том, как их использовать. https://dept.stat.lsa.umich.edu/~jerrick/courses/stat701/notes/parallel.html
Ответ №1:
(отказот ответственности: Я автор)
Пакет future.apply предоставляет взаимно однозначные параллельные версии всех функций R apply. Поскольку он работает поверх платформы future, он работает практически со всеми известными параллельными серверными системами в R.
library(future.apply)
plan(multicore) ## forked processing
list1 <- list(elem1 = 1:3, elem2 = 4:6, elem3 = 7:9)
list2 <- list(elem1 = 10:12, elem2 = 13:15, elem3 = 15:17)
(result <- future_mapply(FUN = function(x, y){
x y
}, list1, list2, SIMPLIFY = FALSE))
В приведенном выше примере используется разветвленная обработка, точно так же, как parallel::mcmapply()
. Для использования PSOCK cluster workers, который также поддерживается в MS Windows, необходимо, чтобы конечный пользователь установил:
plan(multisession)
С вышесказанным вам не нужно выполнять условное кодирование, например:
if (parallel == "forks") {
...
} else if (parallel == "this") {
...
} else if (parallel == "that") {
...
} else {
...
}
Все, что вам нужно, это один future_mapply()
вызов.
Комментарии:
1. @ HenrikB, это решение работает на моем простом примере. Однако у меня возникла проблема с моим реальным сценарием. Я получаю эту ошибку: Ошибка в get(как.character (FUN), mode = «функция», envir = envir): объект ‘myExpl1’ режима ‘функция’ не найден. Это как если бы глобальная среда не использовалась совместно со всеми сеансами. Я пропустил шаг?
2. Вот мой код; myBiomodData <- future_mapply(fun = функция(a, b, d){ write.csv(as.matrix(print(system.time(w <- mapply(FUN = функция (e, f, g){ mapply(FUN = функция (h, i, j){ mapply(FUN = функция(k, l, m){ BIOMOD_FormatingData(соответственно var = l , expl.var = k, resp.name = m, соответственно.xy = myRespXY) }, h, i, j, SIMPLIFY = FALSE) }, e, f, g, SIMPLIFY = FALSE) }, a, b, d, SIMPLIFY = FALSE)))), «myBiomodData_time.csv») }, myExpl1, myResp1, myRespName1, SIMPLIFY = FALSE)
3.1. Можно явно указать дополнительные глобальные переменные, которые фреймворк future не сможет автоматически обнаружить (см. Справку об этом). 2. Если бы вы могли создать минимальный воспроизводимый пример, который я могу воспроизвести, тогда я мог бы изучить проблему и, возможно, даже исправить восходящий поток. ТАК что комментарии для этого не подходят, поэтому не стесняйтесь публиковать в будущем.применить отслеживание проблем.
4. Дело в том, что если каждый вызов
Opt()
занимает всего лишь короткое время, то распараллеливать его не стоит. Много кода не стоит распараллеливать. Только вы знаете, сколько времениOpt()
занимает. Сравнитеfuture_mapply()
сmapply()
, чтобы понять, стоит ли первое.5. Да, 2 минуты достаточно. Он определенно должен выполняться быстрее параллельно. Если это медленнее, возможно, вы сталкиваетесь с другими узкими местами, например, с нехваткой памяти, что приводит к большой замене файлов. Кстати, обратите внимание, что data.table уже выполняется параллельно, поэтому, если 2 минуты потрачены на data.table , это не поможет запустить другой уровень распараллеливания поверх него. О проблеме с data.table см. github.com/HenrikBengtsson/future/discussions /… .