R语言 并行编程

R语言 并行编程

并行编程是一种软件开发实践,它涉及到将一个计算或任务划分为较小的部分,可以同时或并行执行。并行编程可以通过利用计算机或集群中的多个处理器或核心,帮助提高R代码的性能和效率。并行编程的主要概念是,如果使用一个处理器可以在S秒内完成一个操作,那么当有N个处理器参与时,它应该能够在S/N秒内执行。

在R中进行并行编程的必要性

大多数时候,R的代码只在单核上快速工作。但有时操作会-

  • 消耗太多的CPU时间。

  • 占用过多的内存空间。

  • 从磁盘中读出或写入磁盘时消耗了太多时间。

  • 转移需要花费大量时间。

隐性的平行关系

R为我们提供了强大的库支持。有时,我们甚至在不知情的情况下进行并行编程。这是因为现在的R提供了这样的库,提供了内置的并行性,我们可以在后台使用它们。这样一种隐藏的并行性提高了我们的编程效率。但如果能知道实际发生了什么(甚至在幕后),那就更好了。

让我们考虑一个隐藏并行的例子

并行 BLAS

基本线性代数子程序(BLAS)库是在R中为特定类型的CPU定制的,以便从芯片组的结构中获益。拥有一个优化的BLAS总是有益的,因为它提高了执行的性能。

尴尬的平行主义

尴尬的并行性是统计学和数据科学中的一种常见方法。它能够解决数据科学和统计学中的许多问题。在这种类型的并行中,问题被划分为多个独立的部分,所有的部分都是同时执行的,因为它们之间没有任何联系。

语法

在R中,使用lapply()函数可以实现令人尴尬的并行化。这个函数的语法如下 –

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()函数的工作原理类似于loop-it循环,我们遍历列表中的每个元素并对其应用函数。

现在让我们更深入地了解实际发生的情况——。

我们一个一个地迭代每个元素,这就是为什么当我们对列表中的单个元素应用函数时,其他元素只是在内存中闲置。我们可以在R中并行化这件事。主要的想法是划分列表对象,并把它们放到多个处理器中,然后我们可以同时对列表的所有子集应用该函数。

  • 将清单分成多个处理器。

  • 将提供的函数克隆到多个处理器中。

  • 将该功能同时应用于多个核心。

  • 将来自多个核心的结果合并为一个单一的列表。

  • 显示结果。

R中的并行编程包

R中的并行包随R的安装而来。这个包是两个包的组合:R中的雪和多核。

并行包是专门用来将任务以并行的方式交付给每个内核的。具体来说,它是由mclapply()函数进行的。mclapply()函数类似于lapply,但前者能够将任务分配给多个处理器。mclapply()函数还收集了函数调用的结果,将其合并,并将结果作为一个列表返回,其长度与原始列表相同。请注意,R允许我们使用detectCores()函数来获得系统中存在的内核数量。

让我们考虑以下程序,说明mclapply()函数的工作情况 –

注意 – 请注意,”mc.cores “的值大于1只在非窗口操作系统中工作。所以,下面的代码是在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库来实现并行编程。

示例

# 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()等函数的工作。平行编程是任何编程语言中最重要的概念之一,我相信本教程肯定有助于在数据科学领域获得良好的知识。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程