web-dev-qa-db-fra.com

Comment puis-je faire en sorte que R utilise plus de CPU et de mémoire?

Peu importe l'intensité du calcul R, il n'utilise pas plus de 25% du CPU. J'ai essayé de définir la priorité du rsession.exe à High et même Realtime mais l'utilisation reste la même. Existe-t-il un moyen d'augmenter l'utilisation du processeur de R pour utiliser le plein potentiel de mon système ou y a-t-il un malentendu dans ma compréhension du problème? Merci d'avance pour l'aide.

P.S .: Ci-dessous, une capture d'écran de l'utilisation du processeur. Screenshot of the CPU usage

13
Suraj

La base R est monothread, de sorte que 25% de l'utilisation est attendue sur le processeur à 4 cœurs. Sur une seule machine Windows, il est possible de répartir le traitement entre les clusters (ou les cœurs si vous le souhaitez) à l'aide du package parallèle et du Foreach package.

Tout d'abord, le package parallèle (inclus dans R 2.8.0+, pas besoin d'installer) fournit des fonctions basées sur le package snow - ces fonctions sont des extensions de lapply(). Et le package foreach fournit une extension de la construction for-loop - notez qu'il doit être utilisé avec le package doParallel .

Vous trouverez ci-dessous un exemple rapide de clustering k-means utilisant les deux packages. L'idée est simple: (1) ajuster kmeans() dans chaque cluster, (2) combiner les résultats et (3) sélectionner au minimum tot.withiness.

library(parallel)
library(iterators)
library(foreach)
library(doParallel)

# parallel
split = detectCores()
eachStart = 25

cl = makeCluster(split)
init = clusterEvalQ(cl, { library(MASS); NULL })
results = parLapplyLB(cl
                      ,rep(eachStart, split)
                      ,function(nstart) kmeans(Boston, 4, nstart=nstart))
withinss = sapply(results, function(result) result$tot.withinss)
result = results[[which.min(withinss)]]
stopCluster(cl)

result$tot.withinss
#[1] 1814438

# foreach
split = detectCores()
eachStart = 25
# set up iterators
iters = iter(rep(eachStart, split))
# set up combine function
comb = function(res1, res2) {
  if(res1$tot.withinss < res2$tot.withinss) res1 else res2
}

cl = makeCluster(split)
registerDoParallel(cl)
result = foreach(nstart=iters, .combine="comb", .packages="MASS") %dopar%
  kmeans(Boston, 4, nstart=nstart)
stopCluster(cl)

result$tot.withinss
#[1] 1814438

De plus amples détails sur ces packages et d'autres exemples peuvent être trouvés dans les articles suivants.

16
Jaehyeon Kim

R est, dans la plupart des cas, simple thread. À moins que vous ne le configuriez correctement, vous n'utiliserez qu'un seul cœur à 100%. Je suppose que vous utilisez une machine à quatre cœurs, donc 1 cœur à 100% ressemblera à 25% d'utilisation du processeur.

2
Taylor