R語言並行程式設計
並行程式設計是一種軟體開發實踐,它涉及將計算或任務分解成更小的部分,這些部分可以併發或並行執行。透過利用計算機或叢集中的多個處理器或核心,並行程式設計可以幫助提高 R 程式碼的效能和效率。並行程式設計的主要概念是,如果使用單個處理器在一個操作中需要 S 秒,那麼當涉及 N 個處理器時,它應該能夠在 S / N 秒內執行。
R語言並行程式設計的必要性
大多數情況下,R 程式碼在單個核心上執行速度很快。但有時操作可能會:
消耗過多的 CPU 時間。
佔用過多的記憶體空間。
讀取或寫入磁碟花費的時間過長。
傳輸時間過長。
隱式並行性
R 提供了強大的庫支援。有時,我們甚至在不知不覺中就進行了並行程式設計。這是因為現在的 R 提供了具有內建並行性的庫,我們可以在後臺使用它們。這種隱式並行性提高了我們的程式設計效率。但是瞭解實際發生的事情(即使是在幕後)也是很好的。
讓我們考慮一個隱式並行性的例子
並行基本線性代數子程式 (BLAS)
基本線性代數子程式 (BLAS) 庫是為特定型別的 CPU 在 R 中自定義編碼的,目的是利用晶片組架構的優勢。擁有最佳化的 BLAS 總是很有益的,因為它可以提高執行效能。
容易並行化的並行性
容易並行化的並行性是統計學和資料科學中的一種常見方法。它能夠解決資料科學和統計學中的許多問題。在這種型別的並行性中,問題被分成多個獨立的部分,並且所有部分都被同時執行,因為它們彼此之間沒有任何聯絡。
語法
可以使用 `lapply()` 函式在 R 中實現容易並行化的並行性。此函式具有以下語法:
lapply(list, function)
示例
它接受一個列表和一個函式。它返回一個列表,其長度等於輸入列表。讓我們考慮一個程式來說明此函式的工作原理:
# Creating a list myList <- list(data1 = 1:5, data2 = 10:15) # Use lapply() function and # calculate the mean lapply(myList, mean)
輸出
$data1 [1] 3 $data2 [1] 12.5
正如您在輸出中看到的,已經顯示了列表元素的平均值。
`lapply()` 函式的工作方式類似於迴圈,我們迭代列表的每個元素並將函式應用於它。
現在讓我們更深入地瞭解實際發生的情況:
我們逐一迭代每個元素,這就是為什麼當我們將函式應用於列表的單個元素時,其他元素只是在記憶體中空閒。我們可以在 R 中並行化這件事。主要思想是將列表物件分成多個處理器,然後我們可以同時將函式應用於列表的所有子集。
因此,我們可以使用以下步驟實現並行性:
將列表分解到多個處理器中。
將提供的函式克隆到多個處理器中。
同時將函式應用於多個核心。
將來自多個核心的結果組合到單個列表中。
顯示結果。
R中的並行程式設計包
R 中的 `parallel` 包隨 R 的安裝一起提供。此包結合了 R 中的兩個包:`snow` 和 `multicore`。
`parallel` 包專門用於以並行方式將任務交付給每個核心。具體來說,它是透過 `mclapply()` 函式執行的。`mclapply()` 函式類似於 `lapply`,但前者能夠將任務分配給多個處理器。`mclapply()` 函式還收集函式呼叫的結果,將它們組合起來,並將其結果作為長度與原始列表相同的列表返回。請注意,R 允許我們使用 `detectCores()` 函式,我們可以用它來獲取系統中存在的核心數量。
讓我們考慮以下程式,它說明了 `mclapply()` 函式的工作原理:
注意 - 請注意,`mc.cores` 的值大於 1 僅在非 Windows 作業系統中有效。因此,以下程式碼是在 Windows 之外的作業系統中執行的。
示例
# Import library
library(parallel)
library(MASS)
# Creating a list
myList <- list(data1 = 1:10000000, data2 = 1:100000000)
cat("The estimated time using lapply() function:
")
# Calculate the time taken using lapply
system.time(
results <- lapply(myList, mean)
)
# Get the number of cores
numberOfCores <- detectCores()
cat("The estimated time using clapply() function:
")
# Calculate the time taken using lapply() using mclapply()
system.time(
results <- mclapply(myList, mean, mc.cores = numberOfCores)
)
輸出
The estimated time using lapply() function: user system elapsed 0.40 0.00 0.43 The estimated time using clapply() function: user system elapsed 0.12 0.00 0.17
您可以在輸出中看到使用 `apply()` 和 `mcapply()` 函式時的差異。
使用 foreach 和 doParallel 包進行並行程式設計
現在我們將看到如何使用 R 中的 `foreach` 庫實現並行程式設計。但在進入正題之前,讓我們看看 R 中基本的 for 迴圈是如何工作的:
示例
# Iterate using the for loop from 1 to 5
# And print the square of each number
for (data in 1:5) {
print(data * data)
}
輸出
[1] 1 [1] 4 [1] 9 [1] 16 [1] 25
正如您在輸出中看到的,從 1 到 5 的每個數字的平方都顯示在控制檯上。
Foreach 包
現在讓我們談談 `foreach` 包和方法。`foreach` 包為我們提供了 `foreach()` 方法,我們可以用它輕鬆實現並行程式設計。
語法
如果您尚未在系統中安裝 `foreach` 庫,請在 CRAN 的終端中使用以下命令:
install.packages("foreach")
`foreach` 方法類似於基本的 for 迴圈方法,但前者使用 `%do%` 運算子,這意味著執行特定型別的表示式。兩者在返回資料結構方面也有所不同。
示例
考慮以下程式,它說明了 `foreach` 方法的工作原理:
# Import foreach library
library(foreach)
# Iterate using the foreach loop from 1 to 5
# And print the square of each number
foreach (data=1:5) %do% {
data * data
}
輸出
[[1]] [1] 1 [[2]] [1] 4 [[3]] [1] 9 [[4]] [1] 16 [[5]] [1] 25
正如您在輸出中看到的,從 1 到 5 的每個數字的平方都顯示在控制檯上。
doParallel 包
`doParallel` 包為我們提供了 `%dopar%` 運算子,我們可以將其與 `foreach` 一起使用。透過將此運算子與 `foreach` 一起使用,我們將能夠為每次迭代使用不同的處理核心。您可以使用 CRAN 中的以下命令下載“doParallel”包:
install.packages("doParallel")
示例
現在讓我們考慮以下程式,它演示了 `foreach` 方法以及 `%dopar%` 運算子的工作原理:
# Import foreach library
library(foreach)
library(doParallel)
library(MASS)
# Get the total number of cores
numOfCores <- detectCores()
# Register all the cores
registerDoParallel(numberOfCores)
# Iterate using the for loop from 1 to 5
# And print the square of each number
# Using parallelism
foreach (data=1:5) %dopar% {
print(data * data)
}
輸出
[[1]] [1] 1 [[2]] [1] 4 [[3]] [1] 9 [[4]] [1] 16 [[5]] [1] 25
從 1 到 5 的每個數字的平方都顯示在控制檯上。
結論
在本教程中,我們討論了 R 中的並行程式設計。我們討論了 `foreach` 和 `doParallel` 等庫,可以使用它們在 R 中實現並行程式設計。我們還了解了 `mcapply()` 等函式的工作原理。並行程式設計是任何程式語言最重要的概念之一,我相信本教程肯定有助於在資料科學領域獲得良好的知識。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP