推 Wush978:我之前是用Rmpi和snow來跑 06/16 18:56
本篇的 reference
→ gsuper:太好了 sapply 可以這樣做應該可以快超多的 謝謝 06/16 19:06
→ gsuper:你說得"亂數相依"是指 seed default 一開始都相同 06/16 19:13
→ gsuper:所以分配給4核的4次隨機樣本會完全相同的狀況嗎? 06/16 19:13
推 Wush978:ya, 我記得平行運算在這方面是有問題的 06/16 19:49
→ gsuper:OK~~~ 3Q 06/16 20:06
→ clickhere:no,即便是用不同的seed,還是有亂數相依的問題. 06/16 21:27
→ clickhere:除非是獨立的模擬, 否則一般MCMC可能要用parallel的亂數 06/16 21:28
→ clickhere:生成器 SPRNG. google: rsprng 06/16 21:29
→ clickhere:Wush的網誌寫得很好. 可以改用lam/mpi效能會比mpich2好 06/16 21:31
→ clickhere:很多, 但不確定有windows版. 06/16 21:31
→ clickhere:mpi得注意資料在cpu間的傳遞,否則有可能會比開4個R慢的. 06/16 21:33
→ clickhere:multicore用得是process的觀念,就像是linux多工. 06/16 21:40
→ clickhere:內部用fork產生子程序. windows版要自己編. 06/16 21:41
※ 編輯: gsuper 來自: 140.113.239.247 (06/16 23:21)
→ gsuper:之後玩一玩再整理成筆記 06/17 13:35
筆記開始
-------------------------------------------------------------
先安裝 snow 與 Rmpi
在 ubontu 圖形介面下 , 直接在
"管理" -> "Synnaptic 安裝套件"
分別搜尋
r-cran-Rmpi
r-cran-snow
進行安裝
------------------------------------------------------------
http://www.sfu.ca/~sblay/R/snow.html#clusterCall
這是一些 snow 的函式教學
很容易學
主要分成三個步驟
下面有操作簡介
---------------------------------------------------
StepA
cl <- makeCluster(4,type="MPI")
4為想要用的核的數目
type 有很多種
"SOCK","PVM","MPI","NWS" (有空再來學這些東西的意義)
一旦做了以下的指令
library(snow)
cl <- makeCluster(4,type="MPI")
就可以在 top 看到 (linux 的工作管理員)
R 變成 4 組 (平行CPU分配 , 連結成功)
-------------------------------------------------
再來是 StepB
parApply (相同於 apply 的用法 , 但速度比 parCapply 和 parRapply 慢)
parCapply (Column apply , 不需要下 MARGIN=2 的參數)
parRapply ( Row apply , 不需要下 MARGIN=1 的參數)
parSapply
parLapply
這些升級過的函式
重點只有一個
就是在原本的應用方式上
加上一個 cl 變數
比方說
apply ( x,1,paste,collapse="")
parApply (cl,x,1,paste,collapse="")
parRapply(cl,x, paste,collapse="")
------------------------------------------------
StepC
最後一定要記得下一個指令
stopCluster(cl)
把多核的分配結束掉 (資源吃很大)
若 [R] 不正常中止
也需要去 top 自己把程序 kill 掉
不然會變成殭屍程式
------------------------------------------------
以下是我比較速度的程式
我有8核 , 所以開 2~7核 , 測50次
library(snow)
SPEED <- matrix(0,3,8)
rownames(SPEED) <- c("parRapply","parApply","apply")
colnames(SPEED) <- c(paste(1:8,"CORE",sep="_"))
SPEED_MULTI <- list(NULL)
x <- matrix(sample(c("A","T","C","G"),100000,T),50000,2)
for(k in 1:50)
{
for(g in 2:7)
{
cl <- makeCluster(g,type="MPI")
SPEED[1,g] <- system.time(parRapply(cl,x, paste,collapse=""))[3] #平行
SPEED[2,g] <- system.time(parApply (cl,x,1,paste,collapse=""))[3] #平行
SPEED[3,g] <- system.time( apply ( x,1,paste,collapse=""))[3] #非平行
stopCluster(cl)
print(g)
}
SPEED_MULTI[[k]] <- SPEED
}
PAR_RAPPLY <- t(sapply(SPEED_MULTI,function(tmp){tmp[1,c(-1,-8)]}))
PAR_APPLY <- t(sapply(SPEED_MULTI,function(tmp){tmp[2,c(-1,-8)]}))
---------------------------------------------------------
先從單一次的時間測試可看到
在速度上 parRapply > parApply > apply
> SPEED
1_CORE 2_CORE 3_CORE 4_CORE 5_CORE 6_CORE 7_CORE 8_CORE
parRapply 0 0.288 0.226 0.277 0.260 0.235 0.311 0
parApply 0 0.353 0.309 0.451 0.444 0.438 0.434 0
apply 0 0.439 0.464 0.709 0.716 0.742 0.706 0
----------------------------------------------------------
從50次的平均速度來看
開3核似乎是最快的
> colMeans(PAR_RAPPLY)
2_CORE 3_CORE 4_CORE 5_CORE 6_CORE 7_CORE
0.31814 0.24738 0.27184 0.26138 0.25736 0.27146
> colMeans(PAR_APPLY)
2_CORE 3_CORE 4_CORE 5_CORE 6_CORE 7_CORE
0.35836 0.31936 0.36772 0.40882 0.42408 0.43074
------------------------------------------------
從 50 次的標準差來看
有時 4核5核 比較穩定
有時 3核7核 比較穩定
沒有明顯的贏家
> apply(PAR_RAPPLY,2,sd)
2_CORE 3_CORE 4_CORE 5_CORE 6_CORE 7_CORE
0.05133762 0.04803141 0.01216613 0.02597243 0.04290034 0.04530721
> apply(PAR_APPLY,2,sd)
2_CORE 3_CORE 4_CORE 5_CORE 6_CORE 7_CORE
0.04761742 0.04154111 0.05557053 0.05804034 0.04591911 0.02569746
-------------------------------------------------
結論 :
1. 平行運算在速度上
至少可加速一倍
2. 在 Ram 夠用的情況下
開3核或6核較好
但推測每台電腦可能會不一樣
3. 平均效能
6核 > 5核 > 4核 > 7核的原因可能是
我的8核中 , 1個分配給虛擬機
所以實質上是 7 核
由於 linux 也要1核
所以當我開 7 核平行時
搶占 linux 的資源
因此反而速度下降
4. 依舊不能理解的問題
是為什麼 3核 會比 6核 還快
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 15:59)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:01)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:09)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:09)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:10)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:10)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:10)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:15)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:24)
※ 編輯: gsuper 來自: 140.113.239.247 (06/23 16:26)
→ clickhere:good job 06/24 00:58
→ clickhere:copy x到各別的cpu上需要耗時的. 8不一定快. 06/24 00:58
→ clickhere:paste太簡單是另一個原因.再apply中多repeat個幾次,3就 06/24 00:59
→ clickhere:不一定比較快了. Memory也是個問題, 8 可能需要swap. 06/24 01:00
→ clickhere:你用mpich or lam/mpi也有影響. mpich要求8個需要同步. 06/24 01:01
→ clickhere:lam/mpi內定是先到先做,做完可以休息,資源可以暫時丟回 06/24 01:02
→ clickhere:給系統(memory release) 06/24 01:02
→ clickhere:另外apply函數可能測不出真正的差異(它內定做太多雜事) 06/24 01:06
推 ADORIAN:這篇要不要考慮收入精華區? 06/24 09:30
※ 編輯: gsuper 來自: 218.160.244.59 (06/25 04:17)
推 ADORIAN:我有寄信給板主請他考慮收錄此篇, 但沒有任何回應. 06/28 16:25
→ ADORIAN: 尚未得到回應 06/28 16:32
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: gsuper (140.113.239.247), 時間: 03/30/2013 20:32:45
推 Wush978:已收錄至精華區 03/30 23:33
範例 : 計算相關係數
當矩陣極大時 (480000 x 800), 48萬 rows, 800 samples (file size = 3.64Gb)
計算相關係數或 distance matrix
將 800 samples 切分
假設 split = 10
切分成 10 個 480000 x 80 小矩陣
where S = S1, S2, ...., S80
彼此兩兩計算相關係數
where cor(S1,S2)
再合併為1個大相關係數矩陣
則平行運算要開多少核?
split 要下多少才合適?
Ans :
當 split = 5, 需要進行 C5取2 + 5 = 15 次比較
當 split = 10, 需要進行 C10取2 + 10 = 55 次比較
經驗法則, 開平行運算時
核心重複使用會拖慢速度 (若核心數低於計算次數, 也等於核心重複使用)
因此, 上述狀況,
當 split = 5 時, 給 15 核
當 split = 10 時, 開 55 核
core <- ncol(combn(split,2)) + split
以下為實測結果
######################################################
### spearman (samples = 791)
### Row Core Split Time
### 10w 1 1 160s
### 10w 10 5 81s (insufficient core)
### 10w 10 10 114s (insufficient core)
### 10w 10 15 skip (insufficient core)
### 10w 10 20 skip (insufficient core)
### 10w 20 5 48s (1.x times)
### 10w 20 10 68s (insufficient core)
### 10w 20 15 91s (insufficient core)
### 10w 20 20 116s (insufficient core)
### 10w 40 5 50s (2.x times)
### 10w 40 10 57s (insufficient core)
### 10w 40 15 72s (insufficient core)
### 10w 40 20 88s (insufficient core)
### 10w 60 5 50s (4 times)
### 10w 60 10 47s (1.x times)
### 10w 60 15 68s (insufficient core)
### 10w 60 20 91s (insufficient core)
### 10w 15 5 48s * [best match]
### 10w 21 6 46s * [best match]
### 10w 28 7 39s * [best match]
### 10w 36 8 40s * [best match]
### 10w 45 9 40s * [best match]
### 10w 55 10 43s * [best match]
################################################
實測結果顯示
1. 用剛剛好的 cores 數量, 速度最佳, 甚至優於多給 cores
2. split 過大, 對速度沒幫助, 吃的核心變多, 浪費資源
3. 當 split 不足時, 切分的小矩陣過大, 仍會有運算壓力
4. 承3, 可事前測試各個 function 的最大記憶體耐受值, 即可決定 split number
Note :
我是 AMD64核, 記憶體接近無限
由於 speed of Intel CPU >> AMD CPU , 因此本文不適用於 intel CPU
※ 編輯: gsuper (114.32.201.238), 05/04/2015 16:24:55
############################################################
############################################################
############################################################
# foreach 的用法
# 注意存變數會出問題, 要用 res 這個變數來解決
# 直接用於作圖或存出實體檔案都相當不錯
# 盡量讓 loop number %% cores number 能整除
require(doMC)
library(parallel)
registerDoMC(cores = 4)
library(foreach)
res <- foreach(g = 1:ncol(DATA)) %dopar%
{ exprs() }
※ 編輯: gsuper (114.32.201.238), 05/26/2015 14:32:26
※ 編輯: gsuper (114.32.201.238), 05/26/2015 14:33:00
[快速讀檔]
library(data.table)
fread("./table.txt")
※ 編輯: gsuper (114.32.201.238), 06/05/2015 13:57:07
※ 編輯: gsuper (114.32.201.238), 06/05/2015 13:58:54