r优化-使用OpenBLAS可以提高R的性能

R版本: 4.3.2 ide : RStudio RStudio 2023.12.1

运行R代码很慢,cpu利用率很低。

看了很多文章,说是R单核运行。使用OpenBLAS可以提高R的性能。

OpenBLAS 是一种用于优化矩阵和向量操作的开源库 ,使用OpenBLAS可以提高R的性能,这是因为OpenBLAS是一个开源项目,基于GotoBLAS2 1.13 BSD版的开源BLAS库的高性能实现。其中,BLAS(Basic Linear Algebra Subprograms,基础线性代数程序集)是一个应用程序接口(API)标准,用以规范发布基础线性代数操作的数值库(如矢量或矩阵乘法)。大量的数值计算、机器学习库都使用BLAS库进行矩阵运算,这也是诸如深度学习等需要大量计算的情境下,经常会有BLAS库优化的需求。在高性能计算领域,BLAS被广泛使用 。例如,LINPACK的运算成绩则很大程度上取决于BLAS中子程序DGEMM的表现。

除了OpenBLAS之外,优化R代码的其它方法:

  1. 使用向量化操作:R 是向量化编程语言,R 的内置函数往往比用户自定义循环更快。
  2. 应用并行处理:R 语言支持并行处理,需要的包有"parallel", “doParallel"以及"foreach"等,可以根据需要选择使用。
  3. 合理使用数据结构:比如在插入数据时,data.frame相对较慢,而list就会快很多。
  4. 适当编译代码:如果代码中有大量的循环或者条件判断,你也可以考虑使用“cmpfun()”函数进行字节编译来提高性能。你也可以用 Rcpp 来编写 C++ 代码,获得更好的性能。
  5. 利用 OpenBLAS-dll。 最新的版本是OpenBLAS-0.3.26-x64。 下载地址见后面。
  1. 下载OpenBLAS-0.3.25-x64-64.zip文件,找到其中的bin/libopenblas.dll文件,改名为Rblas.dll,放到D:\Program Files\R\R-4.3.1\bin\x64中,替换原有的Rblas.dll;
  2. 下载adda_1.2_win64.zip文件,将其中的libgfortran_64-3.dll文件改名为libgfortran-3.dll,复制到D:\Program Files\R\R-4.3.1\bin\x64;
  3. 将第二步文件中的libquadmath_64-0.dll复制到D:\Program Files\R\R-4.3.1\bin\x64。

上述链接提供了测试用例:

1
2
3
4
5
> a <- matrix(runif(2e3^2), 2e3)
> system.time(b <- crossprod(a))
  
> a <- matrix(runif(4e3^2), 4e3)
> system.time(b <- crossprod(a))

上述代码可以正常运行,且运行速度明显提升。

win11 64位要下载 OpenBLAS-0.3.26-x64.zip 这个包。 而非OpenBLAS-0.3.26-x64-64.zip。

另外 OpenBLAS-0.3.27-x64.zip 对应最新的 R-4.4.1

下载地址:

https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.27/OpenBLAS-0.3.27-x64.zip 对应最新的 R-4.4.1

找到其中的bin/libopenblas.dll文件,改名为Rblas.dll,放到D:\Program Files\R\R-4.3.1\bin\x64中,替换原有的Rblas.dll;

更换前的速度是:

x<-matrix(1:(6000*6000),6000,6000)

system.time(tmp<-x%*%x) 用户 系统 流逝 153.20 0.24 153.49

x<-matrix(1:(6000*6000),6000,6000)

system.time(tmp<-x%*%x) 用户 系统 流逝 28.51 3.03 2.25

https://wd-jishu.oss-cn-hangzhou.aliyuncs.com/img/image-20240307093920845.png@!full

下面设置可以试下:

您需要使用Sys.setenv函数来设置环境变量,就像这样:

1
1Sys.setenv(Rblas_DLL = "D:/Software/R/OpenBLAS-0.3.26-x64/bin/libopenblas.dll")

Renviron.site 文件(如果没有,可以创建一个),然后在文件中添加以下行:

1
Rblas_DLL="D:/Software/R/OpenBLAS-0.3.26-x64-64/bin/libopenblas.dll"

提高R语言代码运行效率的一些其它方法包括:

  1. 使用 Rcpp:Rcpp 会大大简化一些 C++ 的语法特性,使得我们不需要考虑指针、引用等一些复杂的问题。Rcpp 中会提供类似于 R 语言的一些数据结构与语法,使我们更容易理解。因此,要想提高 R 语言的运行速度,Rcpp 是一个非常不错的选择。
  2. 优化读取文件的方式:使用 microbenchmark 包比较各种不同函数读取文件的速度。我们在 R 里面读取大数据的时候总是会出现卡顿,但是很多时候每次都不知道到底哪个读取函数更快。
  3. 避免使用 for 循环,尤其是数据量特别大的时候;避免数据的复制,使用 %>% 之类的管道操作;使用一些更快的 R 包处理数据,比如 data.table;使用 apply、lapply 等函数代替 for;使用 Rcpp 编写 C 语言函数;使用多核并行计算(可以通过lapply来实现)。
  4. 全面理解 R 语言的运行机制,例如 R 是运行时解释编程语言,并且是单线程的,因此你需要避免在程序中使用一些可能导致效率降低的操作

Rcpp和OpenBLAS有不同的应用场景,主要取决于你在R语言中的具体需求。

Rcpp 是用于简化R和C++代码互操作的工具包。如果你需要编写一些在R中效率不高,但在C++中可以快速执行的代码段,那么Rcpp是非常好的选择。Rcpp能使你在不离开R环境的情况下编写、编译和执行C++代码。因此,如果你的计算瓶颈在于某一特定的函数或者闭环,你可以试试是否可以通过将它重写为C++代码并用Rcpp调用来提高速度。

OpenBLAS 是一种用于优化矩阵和向量操作的开源库。如果你的R代码中包含大量的线性代数运算(例如矩阵运算),那么使用OpenBLAS可能会显著提高运算速度,因为OpenBLAS可以有效利用多核和SIMD来加速运算。因此,即使你的R代码已经十分高效,但如果主要的计算负载在矩阵运算,OpenBLAS可能仍能帮助你进一步提高计算效率。

在RStudio中使用Rcpp的步骤包括:

  1. 安装Rcpp包:在R控制台中输入命令install.packages("Rcpp")进行安装。
  2. 加载Rcpp库:在R代码中引入Rcpp库,使用library(Rcpp)
  3. 创建Rcpp函数:使用cppFunction()sourceCpp()函数。「cppFunction」允许你定义C++函数,并在R环境中直接调用。如:
1
2
3
4
5
library(Rcpp)
cppFunction('int add(int x, int y) {
return x + y;
}')
add(2, 3)  # Output: 5

其中,cppFunction函数的输入是一个字符串,这个字符串就是你的C++函数。上述代码定义了一个add函数,这个函数接收两个整数并返回它们的和。

若是你的C++代码比较长,或者是存于外部文件中,这时你就可以使用sourceCpp函数,如:

1
sourceCpp("myfunctions.cpp") # your C++ code is in "myfunctions.cpp"

需要注意的是,这两个Rcpp函数的输入都是原始C++代码,不包括构建和加载共享库所需的其他指令(例如Makefile或其他构建系统文件)。Rcpp会自动为你的代码生成一个上下文,包括必要的头文件和链接指令。

  1. Rcpp函数的使用:如上面的例子,在定义完C++函数后,你可以像调用普通R函数一样直接调用。

RStudio为Rcpp提供了完整的支持,包括通过“Source”按钮和“Ctrl + Shift + Enter”快捷键快速运行C++代码,LUange的诊断等功能。

但是当我要使用WGCNA构建网络时,R在需要调用BLAS时立即崩溃。WGCNA网络构建代码:

1
net <-blockwiseModules(expDataMt, power=power, maxBlockSize=35000, minModuleSize=10,TOMType='signed', networkType = networkType, reassignThreshold=1e-6,mergeCutHeight=mergeCutHeight, numericLabels=TRUE, pamStage = T,pamRespectsDendro=T, saveTOMs=TRUE, corType='bicor',maxPOutliers=0.05, loadTOMs=TRUE, verbose=3,robustY = F, corFnc = 'bicor', deepSplit = deepSplit,saveTOMFileBase=paste(dataSetName, as.character(suffix),'tom', sep='.'))

不会插图。上述代码运行过程中会打印类似“正在调用BLAS进行矩阵相乘计算”之类的提示信息。但使用openBLAS后,在这行信息出现之前,R崩溃了。

请问有人遇到过类似的情况吗?这是什么原因导致的?应该怎么解决?请各位大佬多多指教!

我猜测你可能不应该下载 OpenBLAS-0.3.25-x64-64.zip,而应该下载 OpenBLAS-0.3.25-x64.zip。前面多的那个64是使用64位整数的意思,或许和 R 不兼容。

直接下载替换 dll 是一个安全隐患,和直接运行来路不明的 exe 是一个原理…… 以及还有二进制兼容性问题。

正确的解法是使用 Linux 从源代码编译 OpenBLAS 并链接到 R。ropenblas 自动化了这个过程。

参考:

https://www.douban.com/note/296114898/?_i=2203346w0yKmky

Using Rcpp with the RStudio IDE

R语言教程

随机文章