【編程技巧(三)】并行化+分治:大矩陣運(yùn)算的終極解決方案

在對(duì)一個(gè)大矩陣執(zhí)行相關(guān)性計(jì)算或Jaccard Index的計(jì)算時(shí),其實(shí)執(zhí)行的是矩陣任意兩行(這里假設(shè)要進(jìn)行分析的對(duì)象是矩陣的每個(gè)行)之間的兩兩的計(jì)算,若這個(gè)矩陣的規(guī)模非常龐大,有n行時(shí),計(jì)算的時(shí)間復(fù)雜度就是O(n^2),這個(gè)時(shí)候可以采用并行化策略來加速這個(gè)進(jìn)程(參考上文的 2. R中的并行化方法):

StatOut <- parApply(cl, data, 1, fun, data)

這樣就會(huì)實(shí)現(xiàn)將一個(gè) n vs. n 的問題拆分成 n 個(gè)可以并行解決的 1 vs. n 的問題,當(dāng)然通過設(shè)置線程數(shù)為m,\,(m\le n),使得每次只并行執(zhí)行m個(gè) 1 vs. n 的問題

然后再在函數(shù)fun內(nèi)部再定義一個(gè)并行化計(jì)算來進(jìn)一步并行化加速上面產(chǎn)生的 1 vs. n 的計(jì)算:

fun <- function(vec, data){
    ...
    parApply(cl, data, 1, fun2, vec)
}

在這個(gè)函數(shù)內(nèi)部實(shí)現(xiàn)了將一個(gè) 1 vs. n 的問題拆分成 n 個(gè)可以并行解決的 1 vs. 1 的問題

這樣就實(shí)現(xiàn)了兩步并行化,這樣在保證硬件條件滿足的情況下,的確能顯著加快分析速度

但是并行化技術(shù)會(huì)帶來一個(gè)問題是:雖然時(shí)間開銷減少了,但是空間開銷顯著增加了

比如,第一次并行化,將一個(gè) n vs. n 的問題拆分成 \frac{n}{m} 次可以并行解決的 m個(gè) 1 vs. n 的問題,則需要在每一次并行化任務(wù)中拷貝一個(gè) 1 vs. n 的計(jì)算對(duì)象,即原始有n行的矩陣被拷貝了m次,則相應(yīng)的緩存空間也增加了m倍,很顯然內(nèi)存的占用大大增加了

空間開銷顯著增加帶來的后果就是,很容易導(dǎo)致運(yùn)行內(nèi)存不足程序運(yùn)行中斷的問題,那該怎么解決這個(gè)問題呢?

可以采用分治方法(Divide-Conquer),將原始大矩陣,按照行拆分成多個(gè)小的子塊,對(duì)每個(gè)子塊執(zhí)行計(jì)算,從而得到每個(gè)子塊的運(yùn)算結(jié)果,最后再講每個(gè)子塊的結(jié)果進(jìn)行合并:

n_row <- nrow(data)
nblock <- 10 # 用于設(shè)定子塊的數(shù),用戶可以自行指定
# 該列表變量用于保存每個(gè)子塊的計(jì)算結(jié)果,若總共拆成了m個(gè)子塊,
# 因?yàn)橐M(jìn)行任意兩子塊的計(jì)算,因此會(huì)有mxm個(gè)子塊計(jì)算結(jié)果,因
# 此該列表要保存的數(shù)據(jù)為mxm維度的數(shù)據(jù),每個(gè)元素為一個(gè)計(jì)算結(jié)
# 果,它們都是矩陣
StatOutList <- vector("list", nblock) 

# 1. 開始進(jìn)行分塊計(jì)算
print("[Divide-Conquer]Start carry out Divide-Conquer for Large Observed Matrix")
print("##################################################")
for(i in 1:nblock){
    for(j in 1:nblock){
        nrow_start <- (i-1)*nrow_block+1
        nrow_end <- i*nrow_block
        # 并行化計(jì)算
        if(!is.na(Args[2])){
            print(paste("[Divide-Conquer]Start carry out statistic Jaccard Index parallel for block: ",i,"-",j,sep=''))
            StatOutList[[i]] <- append(StatOutList[[i]], parApply(cl, data[nrow_start:nrow_end,], 1 , JaccardIndexSer, data))
            print(paste("[Divide-Conquer]Finish run parallel for block: ",i,"-",j,sep=''))
        # 串行計(jì)算
        }else{
            print(paste("[Divide-Conquer]Start carry out statistic Jaccard Index serially for block: ",i,"-",j,sep=''))
            StatOutList[[i]] <- append(StatOutList[[i]], apply(data, 1 , JaccardIndexSer, data))
            print(paste("[Divide-Conquer]Finish run serially for block: ",i,"-",j,sep=''))
        }
    }
}

# 2. 結(jié)束分治方法的分塊計(jì)算
if(!is.na(Args[2])){
    print("##################################################")
    print("[Divide-Conquer]Finish parallel running for statistic Jaccard Index!")
    stopCluster(cl)
}else{
    print("##################################################")
    print("[Divide-Conquer]Finish serial running for statistic Jaccard Index!")
}

# 3. 開始進(jìn)行子塊結(jié)果的合并
print("[Divide-Conquer]Start bind sub-block statout")
StatOut <- vector("list", nblock)
# 先對(duì)列進(jìn)行合并
for(i in 1:nblock){
    for(block in StatOutList[[i]]){
        StatOut[[i]] <- cbind(StatOut[[i]], block)
    }
}
# 再對(duì)行進(jìn)行合并
StatOutMerge <- data.frame()
for(block in StatOut){
    StatOutMerge <- rbind(StatOutMerge, block)
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、實(shí)驗(yàn)?zāi)康?學(xué)習(xí)使用 weka 中的常用分類器,完成數(shù)據(jù)分類任務(wù)。 二、實(shí)驗(yàn)內(nèi)容 了解 weka 中 explo...
    yigoh閱讀 8,869評(píng)論 5 4
  • 線性代數(shù)在科學(xué)領(lǐng)域有很多應(yīng)用的場(chǎng)景,如下: 矩陣,是線性代數(shù)中涉及的內(nèi)容, 線性代數(shù)是用來描述狀態(tài)和變化的,而矩陣...
    zhoulujun閱讀 12,646評(píng)論 3 44
  • 一前言 特征值 奇異值 二奇異值計(jì)算 三PCA 1)數(shù)據(jù)的向量表示及降維問題 2)向量的表示及基變換 3)基向量 ...
    Arya鑫閱讀 11,187評(píng)論 2 43
  • 你面浮笑靨 仿佛閱盡滄桑 也必?cái)y著繾綣 還有 尚未洞徹的容顏 踽踽小舟泛波的那場(chǎng)微雨 你一步一蓮 卻懂了 淡默的憂...
    自由是風(fēng)箏閱讀 201評(píng)論 1 4
  • 鬼混了兩年半的學(xué)渣,也就是我準(zhǔn)備跨專業(yè)考研了,報(bào)最熱門的專業(yè)金融,去最壓抑的城市北京,邂逅一座自己喜歡的學(xué)校。 今...
    王曉曉DE小屋閱讀 264評(píng)論 0 0

友情鏈接更多精彩內(nèi)容