Объект параллельной общей памяти R (Windows)

У меня есть большая таблица данных. Каждый параллельный процесс читает из него, обрабатывает данные и возвращает гораздо меньшую таблицу данных. Я не хочу, чтобы большое DT копировалось во все процессы, но, похоже, функция %dopar% в пакете foreach должна копировать.

Есть ли способ сделать объект общим для всех процессов (в окнах)? То есть, используя пакет, отличный от foreach.

Пример кода

library(doParallel)
cluster = makeCluster(4)
registerDoParallel(cluster)

M = 1e4 # make this larger 
dt = data.table(x = rep(LETTERS, M), y = rnorm(26*M))
res = foreach(trim = seq(0.6, 0.95, 0.05), .combine = rbind) %dopar% {
  dt[, .(trimmean = mean(y, trim = trim)), by = x][, trim := trim]
}

(Меня не интересует лучший способ сделать это в data.table без использования parallel. Это просто для того, чтобы показать случай, когда подпроцессы должны читать все данные для обработки, но никогда не изменять их)


person jf328    schedule 03.03.2016    source источник
comment
stackoverflow.com/questions/31575585 /   -  person admccurdy    schedule 03.03.2016
comment
Вот откуда я взял информацию, которую foreach должен скопировать. ищу другие возможности   -  person jf328    schedule 04.03.2016
comment
Я обычно использую снег для параллельного кодирования и не сталкивался с проблемами памяти, поэтому, если я запутался, дайте мне знать. В вашем коде dt изменяется на каждой итерации foreach, поэтому ссылку, которую я разместил, необходимо скопировать, изменить, а затем вернуть. Похоже, если вы назначаете результаты операции другому объекту, он не будет копироваться каждым процессом, а только читаться. Теперь я не уверен, как это будет работать с поведением data.table при изменении структур на месте ... возможно, попробуйте ту же задачу dplyr и назначьте ее другому объекту, чтобы увидеть, есть ли разница.   -  person admccurdy    schedule 04.03.2016
comment
@AdamMccurdy, dt не изменяется в подпроцессе, он только читается. Первый [] возвращает новый data.table, а затем новый изменяется во втором [].   -  person jf328    schedule 04.03.2016


Ответы (1)


Поскольку R не является многопоточным, параллельные рабочие процессы реализованы в виде процессов в различных пакетах параллельного программирования. Одной из особенностей процессов является то, что их память защищена от других процессов, поэтому программы должны использовать специальные механизмы для совместного использования памяти между различными процессами, такие как файлы с отображением памяти. Поскольку R не имеет прямой встроенной поддержки любого такого механизма, были написаны такие пакеты, как «bigmemory», которые позволяют создавать объекты, которые могут совместно использоваться различными процессами. К сожалению, пакет data.table не поддерживает такой механизм, поэтому я не думаю, что есть способ сделать то, что вы хотите.

Обратите внимание, что память может быть разделена «только для чтения» между процессом и разветвленным дочерним процессом в операционных системах Posix (таких как Mac OS X и Linux), поэтому вы можете делать то, что хотите, используя бэкэнд «doMC», но это не работает в Windows, конечно.

person Steve Weston    schedule 06.03.2016