2013-12-06 2 views
6

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

Функция изменяет сам объект, поэтому я перезаписываю оригинальный объект новым. Поскольку объект является списком, и я только модифицирую его небольшую часть, я надеялся, что семантика копирования экземпляра R не позволит сделать несколько копий; однако, при его запуске, похоже, это не так, как я делаю. Вот небольшой пример базовых методов R, которые я использовал. Он правильно сбрасывает весы до нуля.

## make a list of accounts, each with a balance 
## and a function to reset the balance 
foo <- lapply(1:5, function(x) list(balance=x)) 
reset1 <- function(x) {x$balance <- 0; x} 
foo[[4]]$balance 
## 4 ## BEFORE reset 
foo <- mclapply(foo, reset1) 
foo[[4]]$balance 
## 0 ## AFTER reset 

кажется, что использование Эталонные классов может помочь, как они изменчивы, и при использовании lapply это сделать, как я ожидал; баланс сбрасывается до нуля.

Account <- setRefClass("Account", fields=list(balance="numeric"), 
         methods=list(reset=function() {balance <<- 0})) 

foo <- lapply(1:5, function(x) Account$new(balance=x)) 
foo[[4]]$balance 
## 4 
invisible(lapply(foo, function(x) x$reset())) 
foo[[4]]$balance 
## 0 

Но когда я использую mclapply, это не правильно сбросить. Обратите внимание, что если вы находитесь в Windows или имеете mc.cores=1, вместо этого вызывается lapply.

foo <- lapply(1:5, function(x) Account$new(balance=x)) 
foo[[4]]$balance 
## 4 
invisible(mclapply(foo, function(x) x$reset())) 
foo[[4]]$balance 
## 4 

Что происходит? Как я могу работать с базовыми классами параллельно? Есть ли лучший способ избежать ненужного копирования объектов?

+0

Я не могу воспроизвести ваше поведение. он сбрасывается хорошо для меня с 'mclapply' (я получаю 0 баланс). Нужно ли мне сначала вводить номера ядра? – agstudy

+0

Ну, это интересно, @agstudy. Я попробовал это снова здесь, и происходит то же самое. Что вы подразумеваете под вашими вторыми предложениями? Мне это непонятно. – Aaron

+1

@agstudy, мне интересно, если вы работаете в Windows, где вместо этого просто вызывается 'lapply'. Обновленный вопрос для размышлений. – Aaron

ответ

2

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

foo <- mclapply(foo, function(x) {x$reset(); x}) 
foo[[4]]$balance 
## 0 
Смежные вопросы