2009-12-29 58 views
4

我想知道是否有任何方法讓R中的foreach包使用預分配結構來放置結果。基本上它涉及大量的小型龍頭操作。Foreach函數中的內存使用

我非的foreach原來的代碼是一樣的東西

results <- rep(NA,m*l*[big.number]) 
dim(results) <- c(m,l,[big.number]) 
for (i in 1:m){ 
    for (j in 1:l){ 
     results[i,j,] <- function(j,i,data) 
    } 
} 

我想使用的foreach和DOMC並行這一點,但試運行是真的慢,我認爲這是持續的數據移動是rbind和c做。

+0

我還發現,因爲'doMC'使用'fork','result'實際上不會在主進程中設置。你只能通過'combine'函數來組裝結果。 –

回答

0

我有運氣與abind()(從庫(abind))。例如,假設我有一個模擬函數返回矩陣,我想要一個大數組,我可以使用abind(,along = .5)來獲得將矩陣列表綁定到一個數組中並添加了一個新維度。所以你可能會喜歡這樣的東西:

myfun<-function(arr){abind(arr,along=.5)} 

foreach(1:n.sims,.combine=myfun) .... 
0

也許我在這裏錯過了一些東西。單功能(i,j,數據)呼叫的費用應該是不變的,以便在for -loop中還是通過foreach呼叫。你能不能在串口模式下嘗試foreach,那麼可以用multicore(除非你在Windows上)嘗試並從那裏出發?

+0

我想我對doMC結構的兩個方面感到困惑。建立員工的固定成本是多少?移動數據的成本是多少。 在我的情況下,運行函數(i,j,data)的單次迭代大約是200秒,但是在多核中運行兩次需要大約12分鐘。 –

2

這不是一個答案,但我想我會在希望別人會知道什麼是發佈一些測試結果是怎麼回事:

> data <- matrix(rnorm(1000 * 10000), nrow=10000) 
> system.time(foreach(j=1:1000, .combine = function(...) NULL, .multicombine=TRUE) %do% { sum(data[,j]) }) 
utilisateur  système  écoulé 
     0.643  0.031  0.674 
> system.time(foreach(j=1:1000, .combine = function(...) NULL, .multicombine=TRUE) %dopar% { sum(data[,j]) }) 
utilisateur  système  écoulé 
     0.613  0.215  0.653 
> system.time(foreach(j=1:1000) %dopar% { sum(data[,j]) }) 
utilisateur  système  écoulé 
     0.537  0.122  0.745 
> system.time(foreach(j=1:1000) %do% { sum(data[,j]) }) 
utilisateur  système  écoulé 
     0.650  0.028  0.681 
> system.time (for (j in 1:1000) { sum(data[,j]) }) 
utilisateur  système  écoulé 
     0.153  0.069  0.222 

總之,使用內置for仍比路快串行foreach。通過使用dopar並不是真正的勝利,並且看起來並不是所有的東西都是一樣的(它可能仍然是將數據傳回給主人需要很長時間)。你也可以爭辯說,通過這種簡單的計算,開銷自然會佔主導地位。因此,讓我們做一些更復雜的東西:

> data <- matrix(rnorm(3000 * 10000), nrow=10000) 
> system.time (for(j in 1:6000) { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) }) 
utilisateur  système  écoulé 
    11.215  1.272  12.490 
> system.time (foreach(j=1:6000, .combine=c) %do% { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) }) 
utilisateur  système  écoulé 
    14.304  0.468  15.788 
> system.time (foreach(j=1:6000, .combine=c) %dopar% { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) }) 
utilisateur  système  écoulé 
    14.377  11.839  10.358 

現在dopar開始勝出,但三人都還是蠻可比性,並內建for並沒有那麼糟糕,即使所有的額外工作。但是通信開銷呢?我們只需返回已轉換的數據(每次迭代10,000個數字),而不是總和。

> system.time (for(j in 1:6000) { lgamma(exp(data[,(j - 1) %% 3000 + 1])) }) 
utilisateur  système  écoulé 
    11.092  1.189  12.302  
> system.time (foreach(j=1:6000, .combine=function (...) NULL, .multicombine=TRUE) %do% { lgamma(exp(data[,(j - 1) %% 3000 + 1])) }) 
utilisateur  système  écoulé 
    14.902  1.867  22.901 
> system.time (foreach(j=1:6000, .combine=function (...) NULL, .multicombine=TRUE) %dopar% { lgamma(exp(data[,(j - 1) %% 3000 + 1])) }) 

^C 

Timing stopped at: 2.155 0.706 241.948 
> 

在這裏,for循環不必擔心保持結果需要大約與以前一樣長。 %do%版本這次花了很多時間。 %dopar%這可能是通過共享內存傳輸結果?我決定在大約4分鐘後殺死它。

相關問題