私は多くの行を持ち、すべての行で私は非線形関数のunirootを計算します。私は今、2日間コードを実行していないクアッドコアのUbuntuマシンを持っています。驚くことではないが、私は物事をスピードアップする方法を探している;-)mapplyを効率的に並列化する方法はありますか?
いくつかの研究の後で、私はただ1つのコアだけが現在使用されており、並列化が行うことに気づいた。もっと深く掘り下げて、あまりにも多くのオーバーヘッドが発生するので、パッケージforeach
が本当に私の問題ではないと結論付けました(おそらく間違っていますか?)(例えば、SO参照)。良い選択肢は、Unixマシンの場合はmulticore
と思われます。特に、pvec
の機能は、ヘルプページを確認した後に最も効率的な機能と思われます。
しかし、私が正しく理解すると、この関数はと1つだけベクトルをとり、それに応じて分割します。私はparallizedすることができる関数が必要ですが、mapply
のようにベクトル(またはdata.frame
)の代わりに複数のベクトルが必要です。そこに私が逃したものはありますか?
ここに私がしたいことの小さな例があります(関数の代わりに使うことができるので、ここにはplyr
の例が含まれていますが、並列化オプションがあります。実装と内部では、それを並列化するforeach
を呼び出して、私はそれが助けないと思います。正しいことですか?)
library(plyr)
library(foreach)
n <- 10000
df <- data.frame(P = rnorm(n, mean=100, sd=10),
B0 = rnorm(n, mean=40, sd=5),
CF1 = rnorm(n, mean=30, sd=10),
CF2 = rnorm(n, mean=30, sd=5),
CF3 = rnorm(n, mean=90, sd=8))
get_uniroot <- function(P, B0, CF1, CF2, CF3) {
uniroot(function(x) {-P + B0 + CF1/x + CF2/x^2 + CF3/x^3},
lower = 1,
upper = 10,
tol = 0.00001)$root
}
system.time(x1 <- mapply(get_uniroot, df$P, df$B0, df$CF1, df$CF2, df$CF3))
#user system elapsed
#0.91 0.00 0.90
system.time(x2 <- mdply(df, get_uniroot))
#user system elapsed
#5.85 0.00 5.85
system.time(x3 <- foreach(P=df$P, B0=df$B0, CF1=df$CF1, CF2=df$CF2, CF3=df$CF3, .combine = "c") %do% {
get_uniroot(P, B0, CF1, CF2, CF3)})
#user system elapsed
# 10.30 0.00 10.36
all.equal(x1, x2$V1) #TRUE
all.equal(x1, x3) #TRUE
、私は上記のSOのリンクからchunkapplyライアン・トンプソンの機能を実装しようとした(だけ処分しましたdoMC
の部分は、私はそれをインストールすることができなかったので、彼の機能を調整した後でも、彼の例は動作します)、 しかしdidnそれを働かせないでください。しかし、それはforeach
を使用しているので、私は上記の同じ議論が適用されると考えました。
#chunkapply(get_uniroot, list(P=df$P, B0=df$B0, CF1=df$CF1, CF2=df$CF2, CF3=df$CF3))
#Error in { : task 1 failed - "invalid function value in 'zeroin'"
PS:私はちょうどunirootを見つけるために必要なステップの数を減らすためにtol
を高めることができることを知っています。しかし、私はすでにtol
を可能な限り大きく設定しています。
大変ありがとうございました。これは私が探していたものです。また、R2.14.0から「並列」が利用可能であることに気づいていませんでした。 –
ようこそ。 Parallelはもちろんそれを使用する前にロードする必要がありますが、標準インストールが付属しています。 –