Назначение столбцов параллельно data.table

Я хотел бы назначить много (до 2000+) столбцов data.table; процесс показался мне чрезвычайно распараллеливаемым, но кажется, что процесс распределяется не очень хорошо data.table многим работникам.

Я ожидал следующего, чтобы работать:

library(data.table)
library(parallel)

NN = 100
JJ = 100

cl = makeCluster(2)
DT = data.table(seq_len(NN))
alloc.col(DT, 1.5*JJ)

clusterExport(cl, c("DT", "NN", "JJ"))
clusterEvalQ(cl, library(data.table))

parLapply(cl, seq_len(JJ), function(jj) {
  set(DT, , paste0("V", jj), rnorm(NN))
})

stopCluster(cl)

Однако это приводит к неясной ошибке:

Ошибка в checkForRemoteErrors(val): 2 узла выдали ошибки; Первая ошибка: Внутренняя ошибка, пожалуйста, сообщите (включая результат sessionInfo()) в datatable-help: oldtncol (0)

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

Нет ли способа добавить столбцы в data.table в параллели?

1 ответ

Следующее действительно работает в Linux (Ubuntu 16.04). (примечание: mcapply не работает на Windows) Мне интересно понять, если это быстрее

> DT <- do.call("cbind",
               mclapply(seq_len(JJ), function(jj) {
  set(DT, , paste0("V", jj), rnorm(NN))
}, mc.cores = detectCores()))

Спектакль

работает на 12 ядрах

NN = 100000
JJ = 100

пользовательская система истекла
1,172 2,756 41,707

NN = 100
JJ = 2000

пользовательская система истекла
4.060 11.152 24.101

NN = 1000
JJ = 2000

пользовательская система истекла
6,580 15,712 139,967

Предложение

Я использую что-то вроде этого, чтобы получить 2M столбцов и 600 строк (все еще не оптимально), надеюсь, что это соответствует вашим требованиям

system.time(
  DT2 <- as.data.table(matrix(rnorm(NN*JJ), ncol = JJ))
)
Другие вопросы по тегам