Ce n'est pas une réponse, mais je pensais que je posterai des résultats des tests dans l'espoir que quelqu'un d'autre saura ce qui se passe:
> 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
En bref, en utilisant la for
builtin est encore beaucoup plus rapide que série foreach
. Vous ne gagnez pas vraiment en utilisant dopar
, et il ne semble pas que tout mettre ensemble est ce qui prend tout le temps (il se peut encore que la transmission des données au maître prenne beaucoup de temps). Vous pouvez également argumenter qu'avec un calcul aussi simple, le surcoût dominera naturellement. Alors, faisons des choses plus compliquées:
> 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
Maintenant dopar
commence à gagner sur mais les trois sont encore assez comparables et for
est builtin pas si mal, même avec tout le travail supplémentaire. Mais qu'en est-il des frais généraux de communication? Au lieu de prendre des sommes, nous retournerons simplement les données transformées (10 000 nombres par itération).
> 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
>
Ici, la boucle for
qui n'a pas à se soucier de garder des résultats prend environ à peu près aussi longtemps qu'auparavant. La version %do%
a pris beaucoup plus de temps cette fois. Et le %dopar%
qui transfère probablement les résultats à travers la mémoire partagée? J'ai décidé de le tuer après environ 4 minutes.
Il se produit aussi pour moi que parce que 'doMC' utilise un' fork', 'results' ne sera pas réellement mis dans le processus maître. Vous pouvez uniquement assembler les résultats via la fonction 'combine'. –