• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rの高速化
 

Rの高速化

on

  • 9,964 views

 

Statistics

Views

Total Views
9,964
Views on SlideShare
9,910
Embed Views
54

Actions

Likes
20
Downloads
88
Comments
0

4 Embeds 54

http://a0.twimg.com 30
https://twitter.com 21
https://twimg0-a.akamaihd.net 2
http://kokitsuyuzaki.site44.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rの高速化 Rの高速化 Presentation Transcript

    • Rの高速化 Kashiwa.R#1 11 / 11 / 11 @antiplastics
    • 自己紹介所属: 東京理科大学大学院 薬学研究科 修士課程2年 (来年からD進学予定)専門: バイオインフォマティクスtwitterアカウント: @antiplastics趣味: バイク、サーフィン、アニメ、読書など研究内容: マイクロアレイデータからの 発現変動遺伝子の検出
    • 扱っているデータの構造 実験1 実験2 実験3 実験287 実験288 実験289 遺伝子1 1.7 3.9 4.8 4.4 2.5 4.8 実験特異的遺伝子 遺伝子2 -3.3 -0.2 0.2 -4.1 3.1 3.1 発現の検出 など 遺伝子5547 -1.2 4.6 -0.9 4.6 -4.4 1.5 遺伝子5548 1.3 2.7 1.6 6.1 -1.4 3.1 遺伝子5549 2.2 3.2 -1.4 1.3 -3.2 2.0 発現変動遺伝子の検出 など 行 (生物の遺伝子数) 列 (実験データの数)*原核生物(大腸菌、緑膿菌など) *ますます増加するデータベースへの登録件数 6000gene *真菌(カビ、酵母など) × *NGS(次世代シーケンサ)の登場 10000gene *真核生物(ヒト、マウスなど) 20000gene 超多次元、多変量の大規模データ!!
    • データ解析の現場の実情 動画
    • 遅い!!!(ノ; _ ;)ノ ┫:・.::結果待ちに数日かかる事もたびたび。計算が速く終わるかどうかは死活問題。
    • Rはパッケージがとても豊富。library(“hogehoge”)とか打ったら小難しい計算も、関数が勝 手にやってくれるからコード行数も少なくて済む。 めちゃくちゃ便利! だが現実問題これだけ遅いと、やってられない時も。 →Rを高速化させて、サクサク研究を進めたい!! →速くしようと思ったらどこまで速くなるかをみてみよう。
    • 使用するマシン iMac(21.5inch) OS: MacOSⅩ10.6.8 SnowLeopard(64bit) CPU: 2.8GHz Intel Corei7(コア数:4) メモリ: 8GB HDD: 1TB 以下全てのプログラムはこのマシン上 で走らせる事とする。
    • 比較する計算以下の数値積分(中点法)により近時的に円周率 πを求める。 = N(ステップ数)が増すほど精度が上がる 今回は1千万(107)ステップで計算する
    • Cのソースコード#include<stdio.h>#include<time.h>#define num_steps 10000000 107という値をとる変数num_stepsを定義int main(void){ clock_t t1, t2; t1 = clock(); int i; double x,pi,sum=0.0,step; step = 1.0 / (double) num_steps; ステップ = 1/107を定義 for(i = 1;i <= num_steps; i++){ x = (i - 0.5) * step; sum = sum + 4.0 / (1.0 + x * x); 各ステップ毎に長方形の面積を } 計算し、最後に和を求める pi = step * sum; printf("%f¥n",pi); t2 = clock(); printf("%f¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); return(0);}
    • Perlのソースコード$t1 = (times)[0];$num_steps = 10000000;$step = 1.0 / $num_steps; for($i = 1;$i <= $num_steps; $i++){ $x = ($i - 0.5) * $step; $sum = $sum + 4.0 / (1.0 + $x * $x); } $pi = $step * $sum; print $pi; print "¥n";$t2 = (times)[0];$t3 = $t2 - $t1;print "$t3 秒¥n";
    • Pythonのソースコードimport sysimport timebefore = time.time()num_steps = 10000000sum = 0step = 1.0 / num_stepsfor i in range(1,num_steps): x = (i - 0.5) * step sum = sum + 4.0 / (1.0 + x * x)pi = step * sumprint piprint "¥n"after = time.time()print "Running Time =", after - before, "s"
    • Rubyのソースコードrequire "benchmark"num_steps = 10000000step = 1.0 / num_stepssum = 0puts Benchmark::CAPTIONputs Benchmark.measure{ for i in 1 .. num_steps x = (i - 0.5) * step sum = sum + 4.0 / (1.0 + x * x) endpi = step * sumputs pi}
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 Python 5.19 3 Perl 5.59 4 Ruby 9.12やはりCは最速。スクリプト言語とCの差は大きい。
    • R <R-2.12.1,64bit> のソースコード *このくらいのステップ数だと32bitのRは使えなくなるので注意。before <- proc.time()num_steps <- 10000000 step <- 1.0 / num_steps summ <- 0 for(i in 1:num_steps){ x <- (i - 0.5) * step summ <- summ + 4.0 / (1.0 + x * x) } pi <- step * summ print(pi)after <- proc.time()print(after – before)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 Python 5.19 3 Perl 5.59 4 Ruby 9.12new 5 R 23.28 遅い…orz
    • Rの高速化手法① プログラム修正before <- proc.time()num_steps <- 1:10000000 num_stepsを変数からベクトルへ変更 step <- 1.0 / 10000000 x <- (num_steps - 0.5) * step for文をやめて、ベクトルに pi <- sum((4.0 / (1.0 + x * x))*step) 一度にアクセスするような 書き方をする print(pi)after <- proc.time()print(after - before)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15new 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R 23.28 スクリプト言語をぶち抜きましたwww
    • Rの高速化手法② apply関数の使用apply関数ファミリー①で行なったベクトル、行列に同時にアクセスするような計算を、より明示的にできる関数。入力データの型、出力データの型の違いなどで、apply(),lapply(), sapply(), mapply(), tapply() がある。
    • Rの高速化手法② apply関数の使用before <- proc.time()num_steps <- 1:10000000step <- 1.0 / 10000000menseki <- function(A){ x <- (A - 0.5) * step 各ステップで長方形の面積を求める計算は、一 y <- 4.0 / (1.0 + x * x) 度関数として定義する return(y*step)}pi <- sum(sapply(num_steps,menseki)) sapplyを使って、配列num_stepsの各要print(pi) 素に関数mensekiを適用する。after <- proc.time()print(after - before)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R 23.28new 7 R(apply) 54.16かえって遅くなった…。ただし、apply関数を覚えておくといい事がある(後述)。
    • Rの高速化手法③ 並列化 snowパッケージを使えば、先程のapply関数が並列に計算できる!applyファミリー snowのでのapplyファミリーapply() parApply() #行列用lapply() parLapply() #リスト用sapply() parSapply() #ベクトル、行列用mapply() × #グループ化されたデータ用tapply() × #規則的なリストの作成× parRapply() #行列の行に対して× parCapply() #行列の列に対して× parMM() #行列同士の掛け算
    • Rの高速化手法③ 並列化before <- proc.time()library("snow")library(“Rmpi”) snowによりMPIクラスターを4個生成cl <- makeCluster(4,type=“MPI")num_steps <- 1:10000000step <- 1.0 / 10000000clusterExport(cl,”step”)menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) 各ステップで長方形の面積を求める計算 return(y*step) は、一度関数として定義する} snow内で並列化対応したsapplyであpi <- sum(parSapply(cl,num_steps,menseki))print(pi) るparSapplyを使うafter <- proc.time()print(after - before)stopCluster(cl)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(snow) 17.35 7 R 23.28 8 R(apply) 54.16
    • Rの高速化手法④ ffパッケージ Rはメモリを逼迫させる。→データはハードディスクから、必要に応じてメモリに ロードしたい。*ベクトル、行列、因子などのデータ: ffパッケージ *行列のデータ: bigmemoryパッケージしかも上記の2つは並列化まであわせてやってくれる!
    • Rの高速化手法④ ffパッケージbefore <- proc.time()library(ff)library(snowfall)sfInit(parallel=TRUE, cpus=4,type=“MPI") 4つのクラスターを生成num_steps <-ff(vmode="integer",1:10000000,length=10000000) step <- 1.0 / 10000000 ff,stepを各クラスsfLibrary(ff) ターにエクスポートsfExport("step")menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) snowfall内でのsapply()である、 return(y*step) sfSapply()を使う}pi <- sum(sfSapply(num_steps,menseki))print(pi)after <- proc.time()print(after - before)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(ff) 17.00 7 R(snow) 17.35 8 R 23.28 9 R(apply) 54.16 snowより若干速いくらい
    • Rの高速化手法⑤ バイトコンパイラーの使用 あらかじめ構文解析後の関数にしておく。 人が見ても何しているのかわからない機械語に近い形式になる。 バイトコンパイル後 list(.Code, list(7L, GETVAR.OP, 1L, LDCONST.OP, 2L, SUB.OP, 3L, GETVAR.OP, 4L, MUL.OP, 5L, ①library(“compiler”) SETVAR.OP, 6L, POP.OP, LDCONST.OP, ②menseki2 <- cmpfun(menseki) 7L, LDCONST.OP, 8L, GETVAR.OP, 6L, ③disassemble(menseki2) GETVAR.OP, 6L, MUL.OP, 9L, ADD.OP, 10L, DIV.OP, 11L, SETVAR.OP, 12L, POP.OP, GETVAR.OP, バイトコンパイル前 12L, GETVAR.OP, 4L, MUL.OP, 13L, RETURN.OP), list({menseki <- function(A){ x <- (A - 0.5) * step x <- (A - 0.5) * step y <- 4/(1 + x * x) y <- 4.0 / (1.0 + x * x) return(y * step) }, A, 0.5, A - 0.5, step, (A - 0.5) * step, x, 4, 1, return(y*step) x * x, 1 +} x * x, 4/(1 + x * x), y, y * step))
    • Rの高速化手法⑤ バイトコンパイラーの使用before <- proc.time()library("compiler")num_steps <- 1:10000000 step <- 1.0 / 10000000menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) return(y*step)}menseki2 <- cmpfun(menseki) バイトコンパイルpi <- sum(sapply(num_steps,menseki2))print(pi)after <- proc.time()print(after - before)
    • 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R(ff) 17.00 7 R(snow) 17.35 8 R 23.28new 9 R(compiler + apply) 41.14 10 R(apply) 54.16
    • 並列化と組み合わせ ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(compiler + ff) 14.41new 7 R(compiler + snow) 15.11 8 R(ff) 17.00 9 R(snow) 17.35 10 R 23.28 11 R(compiler + apply) 41.14 12 R(apply) 54.16
    • Rの高速化手法⑥ R-2.14.0最新VerのR-2.14.0はかなり速い。*全ての基本パッケージの関数があらかじめ、バ イトコンパイルされているとか R-2.4.0 30.1s R-2.8.0 30.8s R-2.9.10 31.7s R-2.10.0 31.7s R-2.11.0 24.2s 64bit化 R-2.12.1 23.28s R-2.13.2 24.4s ? R-2.14.0 ? バイトコンパイル化 の順
    • 最終結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R(compiler + ff) 14.41 7 R(compiler + snow) 15.11 8 R(ff) 17.00 9 R(snow) 17.35new 10 R(2.14.0) 22.01 11 R 23.28 12 R(compiler + apply) 41.14 13 R(apply) 54.16
    • 時間の関係でできなかった 高速化手法• Revolution R インストール時にコア数を勝手に調べて、マルチコア対応に計算を実行してくれる新型R (Windows、Redhat用)。普通のRより2〜3倍速いという噂。• RCCコンパイラー R→C++に変換できます(Windows、Linux用)。• RDBMSの利用 Rでリレーショナルデータベース(MySQL,PostgreSQL,RODBC,MiniSQL)がいじれます。• Hadoop,Mapreduceの利用 http://www.slideshare.net/holidayworking/rmapreduce (以前のTokyo.Rのスライド)• R+クラウドコンピューティング segue: アマゾンがやっているlapply関数を並列に計算してくれるサービス(Mac,Linux用)。 http://code.google.com/p/segue/