r - 矩阵乘法向量 - R 与 Matlab

标签 r matlab performance

我观察到,在 R(版本 3.6.1)中用大矩阵进行向量乘法的矩阵比在 Matlab(版本 2019b)中慢得多,而两种语言都依赖于(相同的?)BLAS 库。请参阅下面的最小示例:

在 Matlab 中:

n=900; 
p=900; 
A=reshape(1:(n*p),[n,p]); 
x=ones(p,1); 
tic()
for id = 1:1000
  x = A*x; 
end
toc()

在 R 中:
n=900
p=900
A=matrix(c(1:(n*p)),nrow=n,ncol=p)
x=rep(1,ncol(A))
t0 <- Sys.time()
for(iter in 1:1000){
  x = A%*%x
}
t1 <- Sys.time()
print(t1-t0)

在使用同一台计算机时,我在 Matlab 中的运行执行时间大约为 0.05 秒,而在 R 中为 3.5 秒。知道这种差异的原因吗?

谢谢。

[编辑]:我在 C 中添加了一个类似的微积分(使用 CBLAS 库,使用 gcc cblas_dgemv.c -lblas -o cblas_dgemv 编译,其中 cblas_dgemv.c 表示下面的源文件)。我得到的运行时间大约为 0.08 秒,这与使用 Matlab 获得的运行时间(0.05 秒)非常接近。我仍在试图找出 R 中如此巨大的运行时间(3.5 秒)的原因。
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include "cblas.h"

int main(int argc, char **argv)
{
  int m=900,adr;
  double *A,*x,*y;
  struct timeval t0,t1;

  /* memory allocation and initialization */
  A = (double*)malloc(m*m*sizeof(double)); 
  x = (double*)malloc(m*sizeof(double));  
  y = (double*)malloc(m*sizeof(double));  
  for(adr=0;adr<m;adr++) x[adr] = 1.; 
  for(adr=0;adr<m*m;adr++) A[adr] = adr;

  /* main loop */
  gettimeofday(&t0, NULL);
  for(adr=0;adr<1000;adr++)
    cblas_dgemv(CblasColMajor,CblasNoTrans,m,m,1.,A,m,x,1,0.,y,1);
  gettimeofday(&t1, NULL);
  printf("elapsed time = %.2e seconds\n",(double)(t1.tv_usec-t0.tv_usec)/1000000. + (double)(t1.tv_sec-t0.tv_sec));

  /* free memory */
  free(A);
  free(x);
  free(y); 

  return EXIT_SUCCESS;
}

请注意,我无法在 cblas_dgemv 例程中设置 y=x。因此,此 C 演算与上述 R 和 Matlab 代码中的演算略有不同。然而,编译是在没有优化标志(没有选项 -O3)的情况下完成的,我检查了在循环的每次迭代中确实调用了矩阵向量乘积(执行 10 倍多的迭代导致运行时间延长 10 倍)。

最佳答案

Here's有点令人震惊:

The precompiled R distribution that is downloaded from CRAN makes use of the reference BLAS/LAPACK implementation for linear algebra operations



“引用 BLAS”是非优化、非加速的 BLAS,与 OpenBLAS 或英特尔 MKL 不同。 Matlab 使用加速的 MKL。

这似乎得到了 sessionInfo() 的证实在我在 macOS 上的 R 3.6.0 中:
> sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

如果我没看错,这意味着默认情况下,R 使用慢速 BLAS,如果您希望它运行得更快,则需要进行一些配置以使其使用快速 BLAS。

这对我来说有点令人惊讶。据我了解,引用 BLAS 通常主要用于测试和开发,而不是用于“实际工作”。

我在 macOS 10.14 上的 R 3.6 与 Matlab R2019b 中得到的时间大致相同:Matlab 中为 0.04 秒,R 中为 4.5 秒。我认为这与使用非加速 BLAS 的 R 一致。

关于r - 矩阵乘法向量 - R 与 Matlab,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60233426/

相关文章:

c++ - 在 C++ 和 Rcpp 中重写慢速 R 函数

r - 使用 data.table 在两列之间交换值

matlab - 获取向量改变值的索引位置

matlab - 在 Matlab 中关闭 "smart behavior"

performance - 什么是最快的 bzip2 解压器?

java - JMX 的使用以及如何用于现有应用程序

r - 在 R 中添加多个向量

r - 我们如何在构建 R 包时设置常量变量?

c++ - 将 Matlab 转换为 C++

performance - Swift 是唯一具有溢出检查算法的(主流)语言吗?