5

などに精通していforeachます%dopar%parallelのオプションにも精通していますcv.glmnet。しかし、次のようにネストされた並列処理をどのように設定しますか?

library(glmnet)
library(foreach)
library(parallel)
library(doSNOW)
Npar <- 1000
Nobs <- 200
Xdat <- matrix(rnorm(Nobs * Npar), ncol = Npar)
Xclass <- rep(1:2, each = Nobs/2)
Ydat <- rnorm(Nobs)

並列交差検証:

cl <- makeCluster(8, type = "SOCK")
registerDoSNOW(cl)
system.time(mods <- foreach(x = 1:2, .packages = "glmnet") %dopar% {
    idx <- Xclass == x
    cv.glmnet(Xdat[idx,], Ydat[idx], nfolds = 4, parallel = TRUE)
})
stopCluster(cl)

並列交差検証ではありません:

cl <- makeCluster(8, type = "SOCK")
registerDoSNOW(cl)
system.time(mods <- foreach(x = 1:2, .packages = "glmnet") %dopar% {
    idx <- Xclass == x
    cv.glmnet(Xdat[idx,], Ydat[idx], nfolds = 4, parallel = FALSE)
})
stopCluster(cl)

2 つのシステム時間については、ごくわずかな差しかありません。

並列処理は行われていますか? または、ネストされた演算子を明示的に使用する必要がありますか?

副次的な質問: クラスター オブジェクトで 8 つのコアが使用可能で、foreachループに 2 つのタスクが含まれている場合、各タスクに 1 つのコアが割り当てられるか (残りの 6 つのコアはアイドル状態のまま)、または各タスクに 4 つのコアが割り当てられますか (8 つのコアすべてを使い果たす)合計で)?特定の時間に使用されているコアの数を照会する方法は何ですか?

4

1 に答える 1

3

並列相互検証の例では、クラスター ワーカーに foreach 並列バックエンドが登録されていないため、cv.glmnet 自体は並列で実行されません。外側の foreach ループは並列に実行されますが、cv.glmnet 関数の foreach ループは実行されません。

外側と内側の foreach ループに doSNOW を使用するには、clusterCall を使用して Snow Cluster ワーカーを初期化できます。

cl <- makeCluster(2, type = "SOCK")
clusterCall(cl, function() {
  library(doSNOW)
  registerDoSNOW(makeCluster(2, type = "SOCK"))
  NULL
})
registerDoSNOW(cl)

これにより、マスターとワーカーの両方に doSNOW が登録され、parallel=TRUEが指定されたときに cv.glmnet への各呼び出しが 2 つのワーカー クラスターで実行されるようになります。

ネストされた並列処理の秘訣は、あまりにも多くのプロセスを作成して CPU (または複数の CPU) をオーバーサブスクライブしないようにすることです。そのため、並列バックエンドを登録するときは注意が必要です。内側の foreach ループが実行されている間、「外側の」ワーカーはあまり機能しないため、合計 6 つのワーカーが作成されますが、私の例は 4 つのコアを持つ CPU には意味があります。クラスターで実行する場合、doSNOW を使用してノードごとに 1 つのワーカーを開始し、次に doMC を使用してそれらのノードのコアごとに 1 つのワーカーを開始するのが一般的です。

この例では計算時間をあまり使用しないため、2 レベルの並列処理を使用する価値はあまりないことに注意してください。さまざまなアプローチの利点を判断するために、より大きな問題を使用します。

于 2014-01-23T22:52:21.903 に答える