2011年6月4日土曜日

Rで円周率計算+並列計算

前回の計算の続きということで、snowパッケージを用いて並列処理させることにより、円周率の近似計算を高速化させることを行った。前回の記事は>>こちら<<である。リンク先の記事に一度目を通してから、以下に進んでほしい。

1行に座標が与えられた行列で、原点からの距離を行ごとに計算するということは並列化可能(ある行の結果が他の行の結果に依存しない)と考えられるので、大規模になるにつれて高速化の効果が出るのではないかというのが、並列計算を思いついたきっかけである。データ数を10倍にしながら、円周率の精度と計算にかかった時刻について調べてみた。並列化したコードは以下の通りである。

library(snow)
set.seed(1)
tens <- 10^c(1:6)
# データ数を10倍しながら、かかる時間を調べている
for( points.num in tens ){
 coords <- matrix(runif(2*points.num),ncol=2)
 start <- proc.time()
 cl <- makeSOCKcluster(rep("localhost",4)) # 4は利用するマシンのコア数
 dist.from.origin <- parRapply(cl,coords,function(x){sqrt(sum(x^2))})
 myPI <- sum(dist.from.origin<1)/points.num*4
 diff.time <- proc.time()-start
 print(diff.time)
}
stopCluster(cl)

makeSOCKclusterで、ローカルマシンの4つのコアに計算を割り振ることにした。また、parRapplyという行方向の計算を行うapplyを並列化した関数で各コアに計算を割り振っている。一般的なparApplyよりも効率がよいこともあるという理由で試している。

並列化しない前回のコードでも同様に、距離計算と円周率計算の箇所のみで処理時間を計測した。次の表が比較した結果である。CPUはCore2Quad 3GHzを用いている。2つの表を比較すると、データが少ないうちは並列化しない方が高速で、データが大きくなると、並列化した方が速くなっていることが分かる。データが少ないうちはデータを割り振ることや、割り振ったものが返ってきた結果をまとめることで、かえって時間がかかるため、並列化のメリットは無いようである。


並列化しない場合の実行時間
行数ユーザシステム経過
10 0 0 0
100 0 0 0
1000 0 0 0
10000 0.24 0.000.23
100000 0.89 0.000.89
100000010.680.0210.75

並列化した場合の実行時間
行数ユーザシステム経過
10 0.010.005.03
100 0.000.002.19
1000 0.020.032.33
10000 0.020.022.53
100000 0.130.083.40
10000000.940.146.48

最後に参考文献として、Rパッケージガイドブック(東京図書)を挙げておく。snowパッケージの英語のマニュアルを読むのがつらいという場合には、日本語で書かれた文献として参照されたい。

追記(2011/11/09)
念のためこちらにも。前回の記事(Rで円周率計算)を読んでいればご存知かとは思いますが、上記のコード中のsqrtは不要です。実行時間が変わるので、コードの修正はしませんが、もう少し高速化することはできます。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計