У меня есть цикл foreach
, который распараллеливает некоторые вычисления на большом наборе данных.Каждый работник записывает свой вывод в файл и возвращает NULL родительскому процессу.
По этой причине в цикле foreach
используется фиктивный сумматор, который просто игнорирует все выходные данные рабочих.Как ни странно, это прекрасно работает для фреймов данных малого и среднего размера, но не для больших.
Конкретно, моя таблица данных, скажем dt , состоит из 7 '237 605 строк и 5'993 уникальных идентификаторов.Каждый работник должен взять один идентификатор и сделать что-то со своими соответствующими данными.
Фактический цикл приведен ниже:
unique_ids = unique(dt$id)
registerDoMC(40)
foreach(i=unique_ids,
.options.multicore=list(preschedule=TRUE),
.export=c('cfun'),
.combine='cfun', .multicombine=TRUE, .maxcombine = 3000,
.inorder=FALSE, .verbose = TRUE) %dopar%
{
DT = dt[id==i]
# do something with DT and write output to file
# ...
# ...
# finished writing to file
0 # return 0 or NULL, doesn't really matter, we don't care
}
Функция объединения игнорирует все (взято из виньетки foreach):
cfun = function(...) {NULL}
В конце концов, все, что меня волнует, это файлы, выводимые каждым рабочим.
Как упоминалось ранее, это отлично работает на небольших наборах данных, например, с 4'009'012 строк и снова 5'993 уникальных идентификаторов.Выходные данные .verbose соответствуют ожиданиям:
numValues: 4993, numResults: 0, stopped: TRUE
setting mc.preschedule option to 1
, а затем после выполнения всех задач:
got results for task 1
numValues: 4993, numResults: 1, stopped: TRUE
returning status FALSE
got results for task 2
numValues: 4993, numResults: 2, stopped: TRUE
returning status FALSE
...
got results for task 4993
numValues: 4993, numResults: 4993, stopped: TRUE
returning status FALSE
evaluating call object to combine results:
fun(accum, result.3001, result.3002, ... result.4993)
returning status TRUE
Это происходит почти мгновенно, так что я получаю контроль над основным процессом Rочень быстро после того, как все рабочие сделаны (другими словами, нет затрат на объединение результатов)
Однако с большой таблицей данных, процесс застревает в:
numValues: 4993, numResults: 0, stopped: TRUE
setting mc.preschedule option to 1
Даже послезадачи завершены, в родительский процесс ничего не отправляется и сбор результатов не производится.
Как я могу отладить / исправить это?
Большое спасибо.