자바 매트릭스 연산 라이브러리의 성능
우리는 실행 시간이 매트릭스 연산에 의해 구속되는 것을 계산하고 있습니다.(관심있는 경우 아래 몇 가지 세부사항).이 경험으로 인해 다음과 같은 질문이 제기되었습니다.
사람들은 행렬 수학에 대한 Java 라이브러리의 성능을 경험했는가(예: 곱하기, 역수 등)?예를 들어 다음과 같습니다.
찾아봤지만 아무것도 못 찾았어요.
속도 비교 상세:
인텔(R) FORTAN (IFORT) 10.1 20070913을 사용하고 있습니다.Apache commons math 1.2 매트릭스 ops를 사용하여 Java(1.6)에 재실장하였으며, 모든 자릿수에 일치합니다.(Java를 원하는 이유가 있습니다.) (Java double, Fortran real*8)Fortran: 6분, Java 33분, 같은 머신.jvisualm 프로파일링은 RealMatrixImpl에서 많은 시간을 소비했음을 보여줍니다.{getEntry,isValidCoordinate}(공개되지 않은 Apache Commons Math 2.0에서는 없어졌지만 2.0은 더 빠르지 않음)Fortran은 Atlas BLAS 루틴(dpotrf 등)을 사용하고 있습니다.
물론 이것은 각 언어의 코드에 따라 다를 수 있지만 대부분의 경우 동등한 매트릭스 연산을 사용합니다.
라이브러리를 수반하지 않는 다른 몇 가지 계산에서 Java는 그다지 느리지 않았고 때로는 훨씬 더 빨랐습니다.
저는 Java Matrix Bench(JMat Bench)의 저자이며, 이 토론에 대한 제 생각을 말씀드리겠습니다.
Java 라이브러리 간에는 큰 차이가 있으며 전체 운영 범위에 걸쳐 명확한 승자는 없지만 최신 성능 결과(2013년 10월)에서 확인할 수 있는 몇 가지 확실한 리더가 있습니다.
대규모 매트릭스를 사용하여 네이티브 라이브러리를 사용할 수 있는 경우 확실한 승자는 시스템에 최적화된 netlib를 갖춘 MTJ입니다(약 3.5배 더 빠릅니다.순수 Java 솔루션이 필요한 경우 MTJ, OjAlgo, EJML 및 Parallel Colt를 선택하는 것이 좋습니다.작은 매트릭스의 경우 EJML이 확실한 승자입니다.
언급하지 않은 라이브러리는 심각한 성능 문제를 나타내거나 주요 기능이 누락되어 있습니다.
내 2센트만 더하면 돼나는 이 도서관들 중 몇 개를 비교했다.3000에 3000의 복식행렬을 곱해 보았습니다.결과는 다음과 같습니다.
C/C++, Octabe, Python 및 R과 함께 멀티스레드 ATLAS를 사용할 경우 소요 시간은 약 4초였습니다.
Java에서 Jama를 사용할 경우 소요시간은 50초였습니다.
Java에서 Colt 및 Parallel Colt를 사용했을 때 소요된 시간은 150초였습니다.
Java에서 JBLAS를 사용하면 JBLAS가 멀티스레드 ATLAS를 사용하기 때문에 소요시간은 다시 약 4초입니다.
그래서 저는 Java 라이브러리의 성능이 그다지 좋지 않은 것이 분명했습니다.단, Java에서 코드를 작성해야 하는 경우 가장 좋은 옵션은 JBLAS입니다.Jama, Colt, Parallel Colt는 빠르지 않습니다.
저는 jblas의 주 저자로 2009년 12월 말에 버전 1.0을 출시했다는 점을 지적하고 싶습니다.패키징 작업을 많이 했습니다.즉, Windows, Linux, Mac OS X, 32비트 및 64비트용 ATLAS 및 JNI 라이브러리와 함께 "뚱보 항아리"를 다운로드할 수 있게 되었습니다.이렇게 하면 클래스 경로에 jar 파일을 추가하는 것만으로 네이티브 성능을 얻을 수 있습니다.http://jblas.org에서 확인하세요!
Apache Commons Math와 jlapack을 비교했습니다.
검정: 랜덤 1024x1024 행렬의 특이값 분해.
기계:인텔(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz, Linux x 64
옥타브 코드:A=rand(1024); tic; [U,S,V]=svd(A); toc
결과 실행 시간---------------------------------------------------------옥타브 36.34초 JDK 1.7u2 64비트jlapack dgesvd 37.78초apache commons 수학 SVD 42.24초 JDK 1.6u30 64비트jlapack dgesvd 48.68초apache commons 산술 SVD 50.59초 네이티브 루틴C에서 호출된 Lapack*: 37.64초인텔 MKL 6.89초(!)
결론적으로 JDK 1.7에서 호출된 jlapack은 lapack의 네이티브 바이너리 성능에 매우 가깝습니다.Linux distro에 부속된 lapack 바이너리 라이브러리를 사용하여 dgesvd 루틴을 호출하여 U, S, VT 매트릭스도 취득했습니다.모든 테스트는 각 실행(옥타브 제외)에서 정확히 동일한 행렬에 대해 2배 정밀도를 사용하여 수행되었습니다.
면책사항 - 저는 선형대수 전문가도 아니고, 위의 어느 라이브러리에도 소속되어 있지 않습니다.이것은 엄밀한 벤치마크가 아닙니다.JDK 1.7~1.6의 성능 향상과 공통 수학 SVD~jlapack의 성능 향상을 비교하고 싶었기 때문에 '홈메이드' 테스트입니다.
특정 라이브러리에 대해서는 코멘트를 할 수 없지만 원칙적으로 Java에서 이러한 작업이 느려질 이유는 거의 없습니다.일반적으로 핫스팟은 컴파일러가 할 것으로 예상되는 작업을 수행합니다.Java 변수에서의 기본적인 산술 연산을 대응하는 머신 명령으로 컴파일합니다(SSE 명령어를 사용하지만 동작당1개만 사용).어레이 요소에 대한 액세스는 예상대로 "원시" MOV 명령을 사용하도록 컴파일되어 할당 방법을 결정합니다.e변수는 가능한 한 등록할 수 있습니다.프로세서 아키텍처를 활용하기 위해 명령 순서를 변경합니다.가능한 예외는 앞서 설명한 바와 같이 핫스팟은 SSE 명령당 한 번의 작업만 수행합니다. 원칙적으로 명령당 여러 작업을 수행하는 환상적으로 최적화된 매트릭스 라이브러리를 가질 수 있습니다. 단, 특정 FORTRAN 라이브러리가 이러한 작업을 수행하는지 또는 그러한 라이브러리가 존재하는지 여부는 알 수 없습니다.만약 그렇다면 현재 Java(또는 적어도 Hotspot)가 이와 경쟁할 수 있는 방법은 없습니다(물론 Java에서 호출할 수 있는 최적화 기능을 사용하여 네이티브 라이브러리를 직접 작성할 수도 있습니다).
그럼 이 모든 것이 무엇을 의미할까요?글쎄요.
- 원칙적으로 더 나은 성능을 가진 도서관을 찾아다닐 가치가 있지만 유감스럽게도 추천할 수는 없다
- 퍼포먼스가 정말 중요한 경우, 매트릭스 연산을 코딩하는 것을 고려해 보겠습니다.그러면 라이브러리는 일반적으로 실행할 수 없는 최적화나 사용하고 있는 라이브러리는 실행할 수 없습니다(멀티프로세서 머신이 있는 경우 라이브러리가 실제로 멀티스레드인지 확인합니다).
행렬 연산의 장애는 데이터를 한 행 또는 다른 행 또는 열로 최적화하는 순서로 저장해야 하므로 행렬 곱셈과 같이 행과 열을 모두 이동해야 할 때 발생하는 데이터 인접성 문제입니다.그러나 코드를 손으로 쓰면 데이터 인접성을 최적화하기 위해 연산을 결합할 수 있습니다(예를 들어 행렬에 변환을 곱하는 경우, 두 라이브러리 함수를 결합하는 대신 전용 함수를 작성하면 열 횡단을 행 횡단으로 변환할 수 있습니다).일상 생활에서와 마찬가지로 라이브러리는 개발 시간을 단축하는 대신 최적의 성능을 제공하지 않습니다.고객은 퍼포먼스가 얼마나 중요한지 판단해야 합니다.
Jeigen https://github.com/hughperkins/jeigen
- 사용 가능한 가장 빠른 무료 C++ 라이브러리 중 하나인 고유 C++ 라이브러리를 랩합니다.http://eigen.tuxfamily.org
- 비교적 간결한 구문(예: 'mmul', 'sub')
- 조밀 행렬과 스파스 행렬 모두 처리
두 개의 고밀도 행렬을 곱하여 빠르게 테스트합니다.
정전기를 수입하다매트릭스유틸*;
int K = 100;
int N = 100000;
DenseMatrix A = rand(N, K);
DenseMatrix B = rand(K, N);
Timer timer = new Timer();
DenseMatrix C = B.mmul(A);
timer.printTimeCheckMilliseconds();
결과:
Jama: 4090 ms
Jblas: 1594 ms
Ojalgo: 2381 ms (using two threads)
Jeigen: 2514 ms
- jama에 비해 모든 것이 빠릅니다:-P
- Jblas에 비해 Jeigen은 빠르지는 않지만 희박한 행렬을 처리합니다.
- Jeigen은 ojalgo에 비해 소요시간은 거의 동일하지만 코어는 1개이므로 Jeigen은 전체 CPU의 절반을 사용합니다.Jeigen은 terser 구문을 가지고 있다. 즉, "mmul" 대 "multiply Right"
http://code.google.com/p/java-matrix-benchmark/에서는 다양한 하드웨어 구성에 대해 Java로 제공되는 다양한 매트릭스 패키지의 벤치마크를 제공하고 있습니다.하지만 그것은 당신 자신의 벤치마크를 대신할 수 없습니다.
성능은 사용하는 하드웨어 유형(CPU, 코어, 메모리, L1-3 캐시, 버스 속도), 매트릭스 크기 및 알고리즘에 따라 달라집니다.라이브러리마다 알고리즘마다 동시성이 다르기 때문에 하나의 답은 없습니다.또한 네이티브 라이브러리가 기대하는 형식으로 변환하는 오버헤드가 사용 사례의 성능 이점을 저해할 수 있습니다(일부 Java 라이브러리는 매트릭스 스토리지에 관한 보다 유연한 옵션을 갖추고 있어 추가적인 성능 최적화에 사용할 수 있습니다).
그러나 일반적으로 JAMA, Jampack 및 COLT는 오래되어 선형 대수에 대해 Java에서 사용 가능한 현재 성능 상태를 나타내지 않습니다.최신 라이브러리는 여러 코어와 CPU 캐시를 보다 효과적으로 사용합니다.JAMA는 레퍼런스 구현으로 성능에 거의 관계없이 교과서 알고리즘을 구현합니다.COLT와 IBM Ninja는 네이티브 라이브러리에 50% 뒤처져 있더라도 Java에서 성능이 가능하다는 것을 보여준 최초의 Java 라이브러리였습니다.
저는 la4j(Java용 선형 대수) 라이브러리의 저자이며, 요점은 다음과 같습니다.3년간 la4j에 종사해 왔습니다(최신 릴리즈는 0.4.0 [2013년 6월 1일]).필요한 최소한의 기능만 다루었으므로 이제서야 성능 분석과 최적화를 시작할 수 있습니다.그래서 la4j는 내가 원하는 만큼 빠르지는 않지만 나는 그것을 바꾸기 위해 많은 시간을 소비하고 있다.
La4j의 새로운 버전을 JMatBench 플랫폼으로 이식하는 중입니다.la4j에서는 훨씬 빠른 내부 매트릭스 포맷, 안전하지 않은 접근기, 매트릭스 승수를 위한 빠른 블로킹 알고리즘 등 몇 가지 개선 사항이 있으므로 새로운 버전이 이전 버전보다 더 나은 성능을 보여주길 바랍니다.
인텔(R) 마스 커널 라이브러리 확인하셨나요?ATLAS보다 성능이 우수하다고 주장합니다.MKL은 Java에서 JNI 래퍼를 통해 사용할 수 있습니다.
Linalg 코드는 Pentium 및 그 이후의 프로세서의 벡터 컴퓨팅 기능(LAPACK, 현재의 Atlas BLAS 등 MMX 확장 기능부터)에 크게 의존하고 있으며, 「환상적으로 최적화된」코드가 아니고, 업계 표준입니다.Java에서 이 성능을 복제하려면 네이티브 라이브러리가 필요합니다.당신이 설명한 것과 같은 퍼포먼스 문제가 있었지만(주로 Choleski의 분해를 계산할 수 있다) 실제로는 아무것도 찾을 수 없었습니다.Jama는 순수한 Java입니다.이는 구현자가 따라야 할 템플릿과 레퍼런스 키트이기 때문입니다.그런 일은 없었지아파치 수학공통 아시죠?COLT는 아직 테스트하지 않았지만, Ninja의 개선에 크게 의존하고 있는 것 같습니다.대부분은 애드혹 Java 컴파일러를 구축함으로써 얻을 수 있을 것 같지 않습니다.이 시점에서, 네이티브 자마의 실장을 구축하기 위한 「단순히」의 노력이 필요하다고 생각합니다.
Pentium 고유의 네이티브 코드가 더 효과적이라는 것을 Varkhan의 게시물을 기반으로 한다.
JBLAS: Atlas용 JNI 래퍼를 사용한 알파 스테이지 프로젝트: http://www.jblas.org
- 작성자의 블로그 투고:http://mikiobraun.blogspot.com/2008/10/matrices-jni-directbuffers-and-number.html
또 다른 프로젝트:http://code.google.com/p/matrix-toolkits-java/
우리는 꽤 큰 규모의 심각한 재무 계산을 위해 COLT를 사용해 왔고 매우 만족해하고 있습니다.매우 프로파일이 높은 코드에서는 COLT 구현을 자사 코드로 교체할 필요가 거의 없었습니다.
자체 테스트(분명히 독립적이지 않음)에서 인텔의 수동 최적화 어셈블러 루틴의 2배 이내라고 생각합니다.이를 잘 사용하기 위한 비결은 설계 철학을 이해하고 관련 없는 객체 할당을 피하는 것입니다.
많은 고차원 매트릭스를 만들고 있다면, 2차원 배열이 아닌 1차원 배열로 바꾸면 Jama를 약 20% 더 빠르게 만들 수 있다는 것을 알게 되었습니다.이는 Java가 다차원 배열을 효율적으로 지원하지 않기 때문입니다.즉, 어레이의 배열을 작성합니다.
Colt는 이미 이것을 하고 있지만, Jama보다 더 복잡하고 강력하다는 것을 알게 되었습니다.이것이 Colt의 단순한 기능이 느린 이유를 설명해 줄지도 모릅니다.
답은 정말 당신이 무엇을 하느냐에 달려있다.자마는 콜트가 할 수 있는 일의 일부를 지지하지 않아 더 큰 차이를 만든다.
jblas 프로젝트를 확인하는 것이 좋습니다.고성능 매트릭스 작업에 BLAS, LAPACK 및 ATLAS를 사용하는 비교적 새로운 Java 라이브러리입니다.
개발자는 Jblas가 MTJ와 Colt에 비해 유리하다는 벤치마크를 게시했다.
3D 그래픽스 애플리케이션의 경우 lwjgl.util 벡터 구현은 위의 jblas보다 약 3배 더 높은 성능을 보였습니다.
나는 4x4 행렬을 가진 vec4의 행렬 곱셈을 100만 번 했다.
lwjgl은 약 18ms로 완료되었으며, jblas는 약 60ms가 소요되었습니다.
(저는 JNI 접근방식은 비교적 작은 곱셈의 빠른 연속 적용에는 그다지 적합하지 않다고 생각합니다.번역/매핑은 실제 곱셈 실행보다 시간이 더 걸릴 수 있습니다.)
UJMP도 있습니다.
자유롭게 이용할 수 있는 자바 선형 대수 라이브러리가 많이 있습니다.http://www.ujmp.org/java-matrix/benchmark/ 안타깝게도 이 벤치마크에서는 매트릭스 곱셈에 대한 정보만 얻을 수 있습니다(테스트를 바꾸면 다른 라이브러리가 각각의 설계 기능을 이용할 수 없습니다).
다양한 행렬 분해를 계산하도록 요청받았을 때 이러한 선형 대수 라이브러리가 어떻게 수행되는지 살펴봐야 합니다.http://ojalgo.org/matrix_compare.html
Matrix Tokits Java(MTJ)는 이미 언급되었지만, 이 스레드에 걸려 있는 다른 사용자에게는 다시 언급할 가치가 있습니다.관심 있는 분들을 위해 MTJ가 아파치 커먼즈 수학 2.0의 linalg 라이브러리를 대체해야 한다는 이야기도 있는 것 같습니다만, 최근 어떻게 진행되고 있는지는 잘 모르겠습니다.
Apache Mahout을 쇼핑 목록에 추가해야 합니다.
언급URL : https://stackoverflow.com/questions/529457/performance-of-java-matrix-math-libraries
'programing' 카테고리의 다른 글
C의 정규 표현: 예? (0) | 2022.08.08 |
---|---|
VueJ는 컴포넌트에서 목록을 다시 렌더링하지 않음 (0) | 2022.08.08 |
스토어 Vuex에서 항목 삭제 (0) | 2022.08.08 |
다른 클래스의 메서드에 대한 Javadoc 링크 (0) | 2022.08.08 |
루트가 변경되면 이전 컴포넌트의 모든 http 요청을 취소합니다. (0) | 2022.08.08 |