在 R 中進行平行化

R 平行程式設計

Nabeel Imam

Data Scientist

實作範例

資料

print(file_list)
 [1] "./uni_data_country/Argentina.csv"
 [2] "./uni_data_country/Armenia.csv"
 [3] "./uni_data_country/Australia.csv"
 [4] "./uni_data_country/Austria.csv"
 [5] "./uni_data_country/Azerbaijan.csv"
 [6] "./uni_data_country/Bahrain.csv"
 [7] "./uni_data_country/Bangladesh.csv"
 [8] "./uni_data_country/Belarus.csv"
 [9] "./uni_data_country/Belgium.csv"
[10] "./uni_data_country/Bolivia.csv"
...

三座大學建築與畢業生,各自標示第 1 至第 3 名排名。

R 平行程式設計

新增欄位

for (file in file_list) {

  df <- read.csv(file)


df$top100 <- NA for (r in 1:nrow(df)) { df$top100[r] <- df$world_rank[r] <= 100 }
write.csv(df, file) }
R 平行程式設計

效能剖析

程式碼

library(profvis)


profvis({
for (file in file_list) { df <- read.csv(file) df$top100 <- NA for (r in 1:nrow(df)) { df$top100[r] <- df$Rank[r] <= 100 } write.csv(df, file) }
})

輸出

來自 profvis() 的剖析輸出。依範例程式,讀取資料花 40 毫秒,填入 `top100` 欄位值花 80 毫秒,其他步驟幾乎即時完成。

R 平行程式設計

來進行平行化

迴圈

  for (file in file_list) {

    df <- read.csv(file)
    df$top100 <- NA

    for (r in 1:nrow(df)) {
      df$top100[r] <- df$Rank[r] <= 100
    }
    write.csv(df, file)
  }

函式

add_col <- function(file_path) {

  df <- read.csv(file_path)
  df$top100 <- NA

  for (r in 1:nrow(df)) {
    df$top100[r] <- df$Rank[r] <= 100
  }
  write.csv(df, file_path)
}


cl <- makeCluster(6)
dummy <- parLapply(cl, file_list, add_col) stopCluster(cl)
R 平行程式設計

實務考量:核心數量

偵測核心數

detectCores()
[1] 8

平行化程式碼

cl <- makeCluster(detectCores() - 2)


dummy <- parLapply(cl, file_list, add_col) stopCluster(cl)
R 平行程式設計

實務考量:叢集類型

PSOCK 叢集(預設)

cl <- makeCluster(detectCores() - 2)
  • 會複製目前的 R 工作階段
  • 核心不共用記憶體
  • 適用所有作業系統(Windows、Mac、Linux)

FORK 叢集

cl <- makeCluster(detectCores() - 2,
                  type = "FORK")
  • 從 R 工作階段建立子行程
  • 核心共用記憶體(比 PSOCK 更快)
  • 不支援 Windows
R 平行程式設計

一起來練習吧!

R 平行程式設計

Preparing Video For Download...