금번 포스트에서는 윈도우 버전의 R의 계산 성능을 향상시키는 팁을 올려본다. 이는 물론 이 문서 에서 힌트를 얻었다는 것을 미리 알려두며, 윈도 버전의 BLAS 라이브러리의 컴파일된 바이너리가 인터넷에 존재해서 가능했다는 점을 미리 밝혀둔다. 만일 그렇다면 직접 윈도우에서 빌드를 하는 수고를 했어야 했다.
리눅스 버전의 경우 심지어 직접 소스를 빌드해야 되며 환경마다 다른 설정이 필요한 부분이 있어서 관련 전문가가 아니면 설정이 힘드나 윈도우는 간단히 라이브러리 복사 만으로 가능하다.
이쪽 세계에서 일반적인 행렬연산 관련 라이브러리인 BLAS 퍼포먼스 통념은 이렇다.
기본 R BLAS < ATLAS BLAS < OpenBLAS(구 GotoBLAS) < MKL(상용)
싱글 프로세스로 동적하는 R의 태생적인 한계 넘어 행렬 연산에서 멀티 스레딩을 가능하게 하는 라이브러리인데, ATLAS BLAS이후만 이 기능이 가능하다. 따라서 관련 dll을 받아서 해당 디렉토리에 복사하면 된다.
아래 방법은 최근 각광을 받고 있는 OpenBLAS 라이브러리 사용법이다. 이 라이브러리는 구동 환경에 최적화해 컴파일 했을 경우 상용인 MKL에 육박하는 성능을 보여준다고 알려져 있으나 필자의 경험상 라이브러리 안정성이 떨어지는 부분을 목격하고 특화버전은 사용하지 않는다. 하지만 최적화 버전이 아닌 일반버전에 대해서 그런 오류 경험은 해보지 못했다.
32비트 R(윈도우 OS) : `$R_HOME/bin/i386/Rblas.dll’을 이곳에서 다운받은 Rblas.dll로 교체한다.
64비트 R(윈도우 OS) : `$R_HOME/bin/x64/Rblas.dll’을 이곳에서 다운받은 Rblas.dll로 교체한다.
아래는 퍼포먼스 차이를 보여주는 시뮬레이션 결과 이다.
먼저 일반 기본 R을 가지고 수행한 결과이다. (필자의 노트북은 Intel core i5, 윈도우 7 64비트 환경이다. R은 3.0.1 버전이다. )
R > source(url("http://r.research.att.com/benchmarks/R-benchmark-25.R"))
필요한 패키지를 로딩중입니다: Matrix
필요한 패키지를 로딩중입니다: lattice
필요한 패키지를 로딩중입니다: SuppDistsR Benchmark 2.5
===============
Number of times each test is run__________________________: 3I. Matrix calculation
———————
Creation, transp., deformation of a 2500×2500 matrix (sec): 1.27
2400×2400 normal distributed random matrix ^1000____ (sec): 0.513333333333334
Sorting of 7,000,000 random values__________________ (sec): 0.85
2800×2800 cross-product matrix (b = a’ * a)_________ (sec): 14.7066666666667
Linear regr. over a 3000×3000 matrix (c = a \ b’)___ (sec): 6.96333333333333
——————————————–
Trimmed geom. mean (2 extremes eliminated): 1.95890456048869II. Matrix functions
——————–
FFT over 2,400,000 random values____________________ (sec): 0.530000000000001
Eigenvalues of a 640×640 random matrix______________ (sec): 0.953333333333328
Determinant of a 2500×2500 random matrix____________ (sec): 3.67
Cholesky decomposition of a 3000×3000 matrix________ (sec): 5.3
Inverse of a 1600×1600 random matrix________________ (sec): 3.62
——————————————–
Trimmed geom. mean (2 extremes eliminated): 2.33098674745337III. Programmation
——————
3,500,000 Fibonacci numbers calculation (vector calc)(sec): 0.956666666666659
Creation of a 3000×3000 Hilbert matrix (matrix calc) (sec): 0.433333333333337
Grand common divisors of 400,000 pairs (recursion)__ (sec): 1.10666666666665
Creation of a 500×500 Toeplitz matrix (loops)_______ (sec): 0.830000000000013
Escoufier’s method on a 45×45 matrix (mixed)________ (sec): 0.519999999999982
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.744641710715528Total time for all 15 tests_________________________ (sec): 42.2233333333333
Overall mean (sum of I, II and III trimmed means/3)_ (sec): 1.50371943787592
— End of test —
다음은 OpenBLAS 라이브러리를 설치한 이후의 퍼포먼스이다.
R > source(url("http://r.research.att.com/benchmarks/R-benchmark-25.R"))
필요한 패키지를 로딩중입니다: SuppDistsR Benchmark 2.5
===============
Number of times each test is run__________________________: 3I. Matrix calculation
———————
Creation, transp., deformation of a 2500×2500 matrix (sec): 1.28
2400×2400 normal distributed random matrix ^1000____ (sec): 0.51333333333334
Sorting of 7,000,000 random values__________________ (sec): 0.866666666666665
2800×2800 cross-product matrix (b = a’ * a)_________ (sec): 1.52333333333333
Linear regr. over a 3000×3000 matrix (c = a \ b’)___ (sec): 0.839999999999994
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.976743319797433II. Matrix functions
——————–
FFT over 2,400,000 random values____________________ (sec): 0.553333333333323
Eigenvalues of a 640×640 random matrix______________ (sec): 5.3
Determinant of a 2500×2500 random matrix____________ (sec): 0.913333333333317
Cholesky decomposition of a 3000×3000 matrix________ (sec): 0.823333333333323
Inverse of a 1600×1600 random matrix________________ (sec): 0.870000000000005
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.868109988162355III. Programmation
——————
3,500,000 Fibonacci numbers calculation (vector calc)(sec): 0.966666666666659
Creation of a 3000×3000 Hilbert matrix (matrix calc) (sec): 0.446666666666668
Grand common divisors of 400,000 pairs (recursion)__ (sec): 1.15333333333335
Creation of a 500×500 Toeplitz matrix (loops)_______ (sec): 0.826666666666673
Escoufier’s method on a 45×45 matrix (mixed)________ (sec): 0.519999999999982
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.746225646591416Total time for all 15 tests_________________________ (sec): 17.3966666666666
Overall mean (sum of I, II and III trimmed means/3)_ (sec): 0.85850294883276
— End of test —
행렬곱 연산만 하더라도 10배에 가까운 수행 성능 차이를 보여주는 것을 볼 수 있다. 만일 CPU 코어수가 더 많았다면 이 차이는 커졌을 것이다.
마지막으로 MKL을 사용하는 Revolution R 6.2(64비트용)를 사용한 테스트 결과이다. (필자가 학생 신분이라 academy버전을 가지고 있어서 테스트 해볼 수 있었다.)
R > source(url("http://r.research.att.com/benchmarks/R-benchmark-25.R"))
패키지 Matrix를 로드중입니다
패키지 SuppDists를 로드중입니다R Benchmark 2.5
===============
Number of times each test is run__________________________: 3I. Matrix calculation
———————
Creation, transp., deformation of a 2500×2500 matrix (sec): 1.20333333333333
2400×2400 normal distributed random matrix ^1000____ (sec): 0.566666666666668
Sorting of 7,000,000 random values__________________ (sec): 0.866666666666665
2800×2800 cross-product matrix (b = a’ * a)_________ (sec): 0.913333333333332
Linear regr. over a 3000×3000 matrix (c = a \ b’)___ (sec): 0.543333333333327
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.76548442022754II. Matrix functions
——————–
FFT over 2,400,000 random values____________________ (sec): 0.560000000000002
Eigenvalues of a 640×640 random matrix______________ (sec): 0.520000000000001
Determinant of a 2500×2500 random matrix____________ (sec): 0.533333333333327
Cholesky decomposition of a 3000×3000 matrix________ (sec): 0.443333333333338
Inverse of a 1600×1600 random matrix________________ (sec): 0.433333333333328
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.497253084696741III. Programmation
——————
3,500,000 Fibonacci numbers calculation (vector calc)(sec): 0.996666666666665
Creation of a 3000×3000 Hilbert matrix (matrix calc) (sec): 0.443333333333333
Grand common divisors of 400,000 pairs (recursion)__ (sec): 0.979999999999995
Creation of a 500×500 Toeplitz matrix (loops)_______ (sec): 0.843333333333334
Escoufier’s method on a 45×45 matrix (mixed)________ (sec): 0.530000000000001
——————————————–
Trimmed geom. mean (2 extremes eliminated): 0.759452128997561Total time for all 15 tests_________________________ (sec): 10.3766666666666
Overall mean (sum of I, II and III trimmed means/3)_ (sec): 0.661207973301435
— End of test —
Revolution R이 곱 연산에서 OpenBLAS보다 1.5배 정도 빠른 것을 볼 수 있다. 하지만 안정성 측면에서 OpenBLAS보다 Revolution R에 더 손을 들어줄 수 있을 것이다.
필자가 해비한 행렬 연산을 한다면 Revolution R을 구매하는 걸 추천하는 이유는 딱 두 가지 이다.
- MKL을 R을 윈도용으로 빌드가 굉장히 까다롭다. 게다가 MKL 라이브러리 가격이 Revolution R 한 카피보다 훨씬 비싸다.
- 리눅스용 MKL로 R을 빌드하는 것이 매우 까다로우며 이를 RStudio와 연동된 환경에서 사용하는 게 쉽지 않다.
MKL라이브러리는 매트랩과 같은 상용 분석 툴에 기본적으로 포함되어 있는 라이브러리이며 이 라이브러리 덕분에 상당한 계산 연산 시간을 줄일 수 있다. 여러분들의 행렬 연산 10일 걸릴것을 하루만에 처리해 준다면 충분히 투자할 만한 가치가 있을 거라 생각한다.
이런 멀티코어 행렬 계산 라이브러리를 R과 사용할 때 주의점이 있는데, Rprof나 system.time 명령을 사용할 시 CPU 시간이 잘못 계산되는 문제가 있다. 따라서 이런 라이브러리를 테스트 할 경우 실제 계산이 완료되기 까지 수행시간만 측정하길 바란다.
윈도우 R 수학연산 성능 향상 시키기 by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.