2013-04-25 2 views
2

В R функция mcparallel() в пакете parallel отбрасывает новую задачу рабочему при каждом вызове. Например, если у моей машины есть N (физические) ядра, и я, например, запускаю задачи 2N, то каждое ядро ​​запускает две задачи, что нежелательно. Я бы хотел, чтобы я мог запускать N задач для N рабочих, а затем, по мере завершения каждой задачи, отправьте следующую задачу в текущее ядро. Есть простой способ сделать это?Возможно ли, в R parallel :: mcparallel, ограничить количество ядер, используемых в любой момент времени?

Мои задачи занимают разные промежутки времени, поэтому отпадает необходимость в серийных задачах серии N. Возможны некоторые способы решения проблемы, такие как проверка количества активных ядер и последующие задания новых задач, когда они стать свободным, но знает ли кто-нибудь о простом решении?

Я попытался установить cl <- makeForkCluster(nnodes=N), который действительно устанавливает N ядер, но они не используются тогда mcparallel(). Действительно, похоже, что нет способа подать cl в mcparallel(). У последнего есть опция mc.affinity, но неясно, как это использовать, и, похоже, она не делает то, что я хочу, (и, согласно документации, ее функциональность зависит от машины).

+0

Вы уверены, что это правда ?! Ну, проверьте 'foreach' в пакете' foreach'. Операторы будут сериализовать задания, когда у вас будет больше заданий, чем ядер. –

+0

Я использовал foreach, но это не подходит для моих целей в этом конкретном случае, потому что трудно (или даже невозможно) остановить всех работников, если в одном из них произошла ошибка. –

+0

У меня такой же вопрос. Есть ли способ определить число активных mcparallel процессов? Таким образом, я могу освободить больше процессов, будет ли количество активных меньше числа физических ядер. – imriss

ответ

0

Я бы предложил использовать параллельные функции более высокого уровня, которые включают эту функцию, а не пытаться заставить функции низкого уровня выполнять то, что вы хотите.

В этом случае попробуйте написать свои задачи как разные аргументы одной функции. Затем вы можете использовать mclapply() с параметром mc.preschedule, установленным в TRUE, а параметр mc.cores - числом потоков, которое вы хотите использовать за раз. Каждый раз, когда задача заканчивается и поток закрывается, создается новый поток, работающий в следующей доступной задаче.

Даже если каждая задача использует совершенно другой бит кода, вы можете создать список функций и передать это функции-обертки. Например, следующий код выполняет две функции за раз.

f1 <- function(x) {x^2} 
f2 <- function(x) {2*x} 
f3 <- function(x) {3*x} 
f4 <- function(x) {x*3} 
params <- list(f1,f2,f3,f4) 
wrapper <- function(f,inx){f(inx)} 
output <- mclapply(params,FUN=calling,mc.preschedule=TRUE,mc.cores=2,inx=5) 

Если потребность быть вы могли бы сделать PARAMS список списков, включая различные параметры, которые должны быть переданы каждой функции, а также определения функции. Я часто использовал этот подход с различными задачами различной длины, и он работает хорошо.

Конечно, может быть, что ваши различные задачи - это просто разные вызовы одной и той же функции, и в этом случае вы можете напрямую использовать mclapply, не создавая функцию обертки.

0

у вас есть по крайней мере 2 возможности:

  1. Как упоминалось выше, вы можете использовать параметры mcparallel в "mc.cores" или "mc.affinity". На платформах AMD «mc.affinity» предпочтительнее, поскольку два ядра имеют одинаковые часы. Например, FX-8350 имеет 8 ядер, но ядро ​​0 имеет такие же часы, что и ядро ​​1. Если вы запускаете задачу только для двух ядер, лучше назначить ее ядрам 0 и 1, а не 0 и 2. mc. сродство ". Цена теряет балансировку нагрузки.

    «mc.affinity» присутствует в последних версиях пакета. См. Журнал изменений, который можно найти при вводе.

  2. Также вы можете использовать инструмент OS для настройки сродства, например. "taskset":

    /usr/bin/taskset -c 0-1/usr/bin/R ...

    Здесь вы делаете свой скрипт для работы только с ядрами 0 и 1.

Имейте в виду, что номера Linux его ядра начинаются от «0». Параллельный пакет соответствует индексированию R, а первый ядро ​​- это номер ядра.

Смежные вопросы