Table of Contents
Faster BLAS in R
R uses BLAS (Basic Linear Algebra Subprograms) and LAPACK (Linear Algebra PACKage) libraries for linear algebra operations. Because the default libraries have not been fully optimized, you could see large increases in speed, for code that is dependent on linear algebra computations, by switching to a different BLAS library. The traditional open source solutions for this have been ATLAS, GotoBLAS (no longer developed), and more recently OpenBLAS (GotoBLAS2 fork).
The Intel MKL (Math Kernel Library) offers a closed source alternative to the options above. The Intel MKL is nice, as it’s designed for Intel processors by Intel, but it has its own license terms and may not have as great performance with AMD processors.
Normally you would compile R and the BLAS libraries from source for the best optimization. However, the process for doing this is dynamic and can result in unexpected behavior. Even using reference BLAS libraries outside of R’s default may not be the best (see this). With that in mind, the following should provide an easy and conservative approach to replacing the standard BLAS.
Faster BLAS in R for Ubuntu
In Ubuntu, you have two free and open source solutions, ATLAS and OpenBLAS. To install ATLAS and OpenBLAS, use
# install OpenBLAS
sudo apt-get install libopenblas-base
# install ATLAS
sudo apt-get install libatlas3-base liblapack3
Fortunately, if you install both, you can easily switch between them using
sudo update-alternatives --config libblas.so.3-x86_64-linux-gnu
which should show
@ubuntu:~$ sudo update-alternatives --config libblas.so.3-x86_64-linux-gnu
There are 3 choices for the alternative libblas.so.3-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/libblas.so.3).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 100 auto mode
1 /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3 35 manual mode
2 /usr/lib/x86_64-linux-gnu/blas/libblas.so.3 10 manual mode
3 /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 100 manual mode
Press <enter> to keep the current choice[*], or type selection number:
Then make sure to choose the corresponding LAPACK. Run
sudo update-alternatives --config liblapack.so.3-x86_64-linux-gnu
which should show
@ubuntu:~$ sudo update-alternatives --config liblapack.so.3-x86_64-linux-gnu
There are 3 choices for the alternative liblapack.so.3-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/liblapack.so.3).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3 100 auto mode
1 /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3 35 manual mode
2 /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3 10 manual mode
3 /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3 100 manual mode
Press <enter> to keep the current choice[*], or type selection number:
To check the currently used LAPACK and BLAS within an R session, run
# These functions will not work on windows OS
La_library()
extSoftVersion()["BLAS"]
To complicate things, there are actually three different versions of OpenBLAS: serial, OpenMP, and pthread (POSIX threads). OpenMP and pthreads allow for parallel processing. It appears that libopenblas-base
installs pthreads by default. Consensus seems to favor OpenMP?
For additional OpenBLAS support in Stan (CmdStan and CmdStanR), see here https://discourse.mc-stan.org/t/speedup-by-using-external-blas-lapack-with-cmdstan-and-cmdstanr-py/25441
To use Intel’s MKL, you can either
- Build R with Intel’s MKL (build guide)
- Install using
apt
as we did with OpenBLAS above- Manually, based on these directions: dirk.eddelbuettel.com or software.intel.com
- Automatically using
sudo apt install intel-mkl
Make sure the following environment variable is added: MKL_THREADING_LAYER=GNU
. Otherwise you will experience numerical errors using intel’s MKL.
Faster BLAS in R for Windows
It’s a bit tougher for Windows. I don’t know of any current precompiled ATLAS or OpenBLAS files that can be dropped in. There are two sources of older optimized BLAS files, here and here, but it’s probably not something you want to rely on. Even worse, Microsoft R Open no longer exists as of June 2021. The current best methods may be to install Intel’s MKL manually, or copy the Intel MKL libraries from an old MRO installation. MRO installs the MKL files at
C:\Program Files\Microsoft\R Open\R-4.0.2\bin\x64\libiomp5md.dll
C:\Program Files\Microsoft\R Open\R-4.0.2\bin\x64\Rblas.dll
C:\Program Files\Microsoft\R Open\R-4.0.2\bin\x64\Rlapack.dll
and these three files can be dropped in and replace the Rblas.dll
and Rlapack.dll
files for the open source R at
C:\Program Files\R\R-4.0.2\bin\x64\
There’s also a few R packages specific to MRO (see Revo*
) that may also be transferred over, though I haven’t tested this.
But, this could be troublesome in a corporate environment:
Microsoft R Services MKL
End User License Agreement
R Services MKL is a software package provided for use with Microsoft R Server,
Microsoft R Open, and any successors or other software applications released by
us ("Licensed Products") that can be used with the Intel® Math Kernel Libraries
("MKL")(for more information, see https://software.intel.com/en-us/intel-mkl).
This software package is referred to herein as the "R Services MKL."
Intel Corporation is referred to as "Intel."
1. License. The R Services MKL is licensed for exclusive use with the Licensed
Products. Subject to all of the terms and conditions of this Agreement, Microsoft
grants User a non-exclusive, non-transferable, non-sublicensable right to use R
Services MKL. R Services MKL must be used as a single integrated software
application and may not be separated into its constituent parts.
Benchmarks
Some artificial benchmarks using the following scripts:
- R-benchmark-25.R as seen from here
- revo-script.R as seen from here
This one is also interesting (from here).
Timings below are rough averages across a handful of runs. Nothing exact or rigorous. I’d ignore any differences within 10% or so.
R benchmark 25
time_sec | cpu | n_cores | r | year | os | blas_lapack |
2.41 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
2.44 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
2.48 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
3.03 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
3.33 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
3.41 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/libopenblasp-r0.3.13.so |
3.45 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/libopenblasp-r0.3.13.so |
3.50 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
4.64 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
5.69 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
6.95 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
7.06 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
7.41 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
10.37 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
19.81 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
20.48 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
27.92 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
28.82 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
32.47 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
32.89 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
Revo Script Matrix Multiply
time_sec | cpu | n_cores | r | year | os | blas_lapack |
1.22 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
1.26 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
1.32 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
2.01 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
3.26 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
3.34 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
4.97 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/libopenblasp-r0.3.13.so |
4.97 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/libopenblasp-r0.3.13.so |
5.81 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
5.99 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
6.08 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
6.72 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
10.94 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
21.37 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
83.58 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
85.01 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
122.44 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
126.43 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
126.47 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
127.50 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
Revo Script Cholesky
time_sec | cpu | n_cores | r | year | os | blas_lapack |
0.25 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
0.26 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
0.27 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
0.37 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
0.55 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
0.58 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
0.89 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/libopenblasp-r0.3.13.so |
0.89 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/libopenblasp-r0.3.13.so |
1.09 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
1.11 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
1.29 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
1.49 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
1.91 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
3.75 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
13.38 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
13.39 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
19.59 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
19.74 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
19.81 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
20.45 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
Revo Script SVD
time_sec | cpu | n_cores | r | year | os | blas_lapack |
1.25 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
1.39 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
1.51 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
1.60 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
1.75 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
1.86 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
2.91 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/libopenblasp-r0.3.13.so |
2.98 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/libopenblasp-r0.3.13.so |
5.26 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
5.41 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
5.91 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
6.20 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
6.88 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
13.88 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
23.50 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
26.27 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
34.67 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
34.70 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
39.21 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
41.78 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
Revo Script PCA
time_sec | cpu | n_cores | r | year | os | blas_lapack |
3.12 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
3.12 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
3.75 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
4.23 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
5.90 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
5.97 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
9.60 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/libopenblasp-r0.3.13.so |
10.56 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/libopenblasp-r0.3.13.so |
13.81 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
14.23 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
15.03 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
17.16 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
19.49 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
41.21 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
91.46 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
98.17 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
130.24 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
130.39 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
142.35 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
153.66 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
Revo Script LDA
time_sec | cpu | n_cores | r | year | os | blas_lapack |
12.27 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Intel MKL 2020.4.304-2 |
12.86 | Intel i5-1135G7 | 4 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
18.01 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | pthread/libopenblasp-r0.3.10.so |
18.44 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | openmp/ibopenblasp-r0.3.13.so |
18.50 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | pthread/ibopenblasp-r0.3.13.so |
18.80 | AMD 5600x | 6 | 4.0.2 | 2021 | Windows 10 | Intel MKL MRO |
19.54 | AMD 5600x | 6 | 4.0.2 | 2021 | Ubuntu 20.04 | Intel MKL MRO |
19.90 | AMD 5600x | 6 | 4.1.0 | 2021 | Ubuntu 20.04 | Intel MKL 2020.0.166-1 |
22.43 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Intel MKL |
23.25 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | OpenBLAS |
23.66 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Intel MKL |
23.91 | Intel i5-3320M | 2 | 4.0.3 | 2021 | Ubuntu 20.04 | OpenBLAS |
28.58 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | atlas/libblas.so.3.10.3 |
41.09 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | ATLAS |
74.37 | AMD 5600x | 6 | 4.0.3 | 2021 | Ubuntu 20.04 | Default |
78.72 | AMD 5600x | 6 | 4.0.3 | 2021 | Windows 10 | Default |
92.82 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Ubuntu 14.04 | Default |
94.40 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Ubuntu 21.04 | Default |
94.62 | Intel i5-1135G7 | 4 | 4.1.0 | 2021 | Windows 10 | Default |
104.58 | Intel i5-3320M | 2 | 3.1.1 | 2014 | Windows 8.1 | Default |
Last Updated: 2021-09-12