BLAS 설정으로 R, numpy 성능 높히기

Tags:

Debian Science Linear Algebra Libraries
Is your NumPy using the right ATLAS?
For faster R use OpenBLAS instead: better than ATLAS, trivial to switch to on Ubuntu

매번 잊어버리는 것이라 적어놓습니다.

R, numpy등은 BLAS(Basic Linear Algebra System)을 사용합니다. BLAS의 구현체에는 레퍼런스구현(libblas), ATLAS구현(libatlas), OpenBLAS구현(libopenblas)가 있고, 이들은 다음 명령으로 찾아볼 수 있습니다. (이하 모두 우분투 명령으로 설명)

~$ sudo apt-cache search --names-only libblas
[sudo] password for mkseo: 
libblas-dev - Basic Linear Algebra Subroutines 3, static library
libblas-doc - Basic Linear Algebra Subroutines 3, documentation
libblas3gf - Basic Linear Algebra Reference implementations, shared library
libatlas-base-dev - Automatically Tuned Linear Algebra Software, generic static
libatlas3gf-base - Automatically Tuned Linear Algebra Software, generic shared
libblas-test - Basic Linear Algebra Subroutines 3, testing programs
libopenblas-base - Optimized BLAS (linear algebra) library based on GotoBLAS2
libopenblas-dev - Optimized BLAS (linear algebra) library based on GotoBLAS2

그리고 이들 중 어떤것을 사용하는가에따라 퍼포먼스가 달라집니다. numpy의 경우 간단하게 다음 명령으로 살펴볼 수 있습니다.

In [1]: >>> from numpy import *
In [2]: >>> import time
In [3]: >>> A = random.random((1000,1000))
In [4]: >>> B = random.random((1000,1000))
In [5]: >>> t = time.time(); dot(A,B); print time.time()-t
0.180840015411

만약 이 코드의 수행시간이 6초 정도 나오면 개선의 여지가 있다고 보면 됩니다.

R이라면 다음과 같이 성능 평가 코드를 다운로드 합니다.

$ wget http://r.research.att.com/benchmarks/R-benchmark-25.R
--2013-12-07 00:26:12--  http://r.research.att.com/benchmarks/R-benchmark-25.R
Resolving r.research.att.com (r.research.att.com)... 207.140.168.126, 2620:0:f00:10::126
Connecting to r.research.att.com (r.research.att.com)|207.140.168.126|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 13666 (13K) [text/plain]
Saving to: `R-benchmark-25.R.1'

100%[============================================================>] 13,666      34.4K/s   in 0.4s    

2013-12-07 00:26:13 (34.4 KB/s) - `R-benchmark-25.R.1' saved [13666/13666]

그 뒤 벤치마크를 수행합니다.

$ cat R-benchmark-25.R | time R --slave
Loading required package: Matrix
Loading required package: SuppDists
Warning messages:
1: In remove("a", "b") : object 'a' not found
2: In remove("a", "b") : object 'b' not found


   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.904666666666667 
2400x2400 normal distributed random matrix ^1000____ (sec):  0.570666666666667 
Sorting of 7,000,000 random values__________________ (sec):  0.671000000000001 
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  1.866 
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  1.018 
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  0.851764683213596 

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.384000000000002 
Eigenvalues of a 640x640 random matrix______________ (sec):  0.763333333333333 
Determinant of a 2500x2500 random matrix____________ (sec):  1.122 
Cholesky decomposition of a 3000x3000 matrix________ (sec):  0.912000000000004 
Inverse of a 1600x1600 random matrix________________ (sec):  1.05066666666667 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.900999755960927 

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  0.634666666666665 
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.320333333333335 
Grand common divisors of 400,000 pairs (recursion)__ (sec):  0.886333333333335 
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.570666666666668 
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.353999999999999 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.504247575798334 


Total time for all 15 tests_________________________ (sec):  12.0283333333333 
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  0.728723386126362 
                      --- End of test ---

각자의 머신 성능에따라 다른 결과가 나올 수 있지만, 위 정도의 속도가 나오지 않으면 개선의 여지가 있습니다.

만약 위 코드 수행중 SuppDists가 없다는 에러가 나면 R 콘솔에서 다음 명령으로 SuppDists를 설치합니다.

> install.packages("SuppDists")

속도 문제가 있으면 libatlas 패키지들이나 libopenblas 패키지들을 설치합니다. 제 경우엔 libatlas 가 성능이 좋았고 다음과 같이 libatlas 패키지들을 찾았습니다.

$ sudo apt-cache search --names-only libatlas
libatlas-base-dev - Automatically Tuned Linear Algebra Software, generic static
libatlas-cpp-0.6-1 - The protocol library of the World Forge project - runtime libs
libatlas-cpp-0.6-1-dbg - The protocol library of the World Forge project - debugging libs
libatlas-cpp-0.6-dev - The protocol library of the World Forge project - header files
libatlas-cpp-doc - The protocol library of the World Forge project - documentation
libatlas-dev - Automatically Tuned Linear Algebra Software, C header files
libatlas-doc - Automatically Tuned Linear Algebra Software, documentation
libatlas-test - Automatically Tuned Linear Algebra Software, test programs
libatlas3gf-base - Automatically Tuned Linear Algebra Software, generic shared

그리고 설치.

$ sudo apt-get install libatlas-base-dev libatlas-dev libatlas3gf-base

설치가되면 update-alternatives로 자동으로 이들이 선택되야하는데 혹시라도 선택이 안되면 다음 명령으로 적절히 선택해줍니다. 아래에 예를 보였는데, 제 경우엔 atlas가 우선순위가 높아서 특별히 선택할 필요는 없었습니다. 참고로 /usr/lib/lapack, /usr/lib/libblas가 참조구현들입니다. ‘atlas’란 단어가 들어간 이름들이 atlas구현이구요. 만약에 libopenblas까지 설치하면 (제 기억이 맞다면) libopenblas가 우선 순위가 가장 높아 기본으로 잡히게 됩니다. 그 경우에는 atlas로 아래 화면에서 선택을 해주어야합니다.

$ sudo update-alternatives --config liblapack.so.3gf
There are 2 choices for the alternative liblapack.so.3gf (providing /usr/lib/liblapack.so.3gf).

  Selection    Path                                        Priority   Status
------------------------------------------------------------
* 0            /usr/lib/atlas-base/atlas/liblapack.so.3gf   35        auto mode
  1            /usr/lib/atlas-base/atlas/liblapack.so.3gf   35        manual mode
  2            /usr/lib/lapack/liblapack.so.3gf             10        manual mode

Press enter to keep the current choice[*], or type selection number: 

$ sudo update-alternatives --config libblas.so.3gf
There are 2 choices for the alternative libblas.so.3gf (providing /usr/lib/libblas.so.3gf).

  Selection    Path                                      Priority   Status
------------------------------------------------------------
* 0            /usr/lib/atlas-base/atlas/libblas.so.3gf   35        auto mode
  1            /usr/lib/atlas-base/atlas/libblas.so.3gf   35        manual mode
  2            /usr/lib/libblas/libblas.so.3gf            10        manual mode

Press enter to keep the current choice[*], or type selection number: 

만약 libblas.so.3gf가 없다는 에러가 나오면 다음 명령을 대신 수행합니다.

$ sudo update-alternatives --config libblas.so.3

여기까지 하고 나서 다시 벤치마킹 해보면 됩니다.

글의 처음에 걸린 링크들에서는 libopenblas를 추천하지만, 실제로 제 머신에서는 numpy나 R에서 에러메시지가 나왔습니다. 그래서 libopenblas는 결국 삭제했습니다.