자바 매트릭스 수학 라이브러리의 성능은? [닫은]


151

우리는 런타임이 행렬 연산에 의해 구속되는 것을 계산하고 있습니다. (관심이 있다면 아래에 몇 가지 세부 사항이 있습니다.)

사람들은 행렬 수학 (예 : 곱하기, 역함수)을위한 Java 라이브러리의 성능에 경험이 있습니까? 예를 들면 다음과 같습니다.

나는 아무것도 찾지 못했다.


속도 비교 세부 사항 :

인텔 FORTRAN (ifort (IFORT) 10.1 20070913)을 사용하고 있습니다. Apache commons math 1.2 매트릭스 ops를 사용하여 Java (1.6)로 다시 구현했으며 모든 정확도에 동의합니다. (Java로 원하는 이유가 있습니다.) (Java는 두 배, Fortran real * 8). 포트란 : 6 ​​분, Java 33 분, 동일한 머신. jvisualm 프로파일 링은 RealMatrixImpl에서 많은 시간을 보냈습니다. Fortran은 Atlas BLAS 루틴 (dpotrf 등)을 사용하고 있습니다.

분명히 이것은 각 언어의 코드에 따라 달라질 수 있지만 대부분의 경우 동등한 행렬 연산에 있다고 생각합니다.

라이브러리를 포함하지 않는 여러 다른 계산에서 Java는 훨씬 느리지 않고 때로는 훨씬 빠릅니다.


까다로운 행렬 수학 연산은 최소한 O (n ^ 3)입니다 ... 더 나빠질
— 수록

2
왜 역수가 필요합니까? 거의 모든 응용 프로그램의 경우 실제 역수가 필요하지 않습니다. 역산을 계산하는 것은 안정성 문제 때문에 나쁜 생각입니다.
— 잉 샤오

1
@Calyth : 그렇습니다, 우리는 시간을 할 수있었습니다. 다른 사람들이 이미 가지고 있는지 궁금했습니다. @Ying Xiao : 그렇습니다. 그 반대는 피해야합니다. 그러나이 계산은 가장 간단하게 사용됩니다. en.wikipedia.org/wiki/…를 참조하십시오 .
— dfrankow

2
@Calyth 잘못 되었으니, 나누기 및 정복 방법을 사용하는 O (n ^ 3)보다 더 효율적인 방법이 있습니다.
— starblue

1
가장 빠른 기본 성능은 JCublas입니다. 빠른 선형 대수가 필요한 경우 GPU가 필요합니다. clMath가있는 JOCL도 작동하고 CPU에 이식 가능하며 (다시 컴파일하지 않은 다중 플랫폼) 테스트하지 않았습니다.
— Aleksandr Dubinsky

답변:


98

내 2 센트 만 추가하면됩니다. 이 라이브러리 중 일부를 비교했습니다. 나는 자신과 함께 3000 곱하기 3000의 곱셈 행렬을 곱하려고 시도했다. 결과는 다음과 같습니다.

C / C ++, Octave, Python 및 R과 함께 멀티 스레드 ATLAS를 사용하는 데 걸리는 시간은 약 4 초였습니다.

Java와 함께 Jama를 사용하는 데 걸리는 시간은 50 초입니다.

Java와 함께 Colt 및 Parallel Colt를 사용하면 소요 시간이 150 초였습니다!

JBLAS를 Java와 함께 사용하면 JBLAS가 멀티 스레드 ATLAS를 사용하므로 약 4 초가 걸렸습니다.

그래서 Java 라이브러리가 너무 잘 수행되지 않았다는 것이 분명했습니다. 그러나 누군가 Java로 코딩해야하는 경우 가장 좋은 방법은 JBLAS입니다. Jama, Colt 및 Parallel Colt는 빠르지 않습니다.


3
멀티 코어 머신을 사용하고 있다고 생각하므로 라이브러리가 멀티 코어를 사용하는지 여부에 따라 이러한 결과가 크게 영향을 받습니까? 예를 들어 mpi 또는 hadoop 등을 사용하여 병렬화하는 경우 mpi / hadoop 구현이 병렬화를 처리 하므로 중요한 시간은 실제로 단일 코어 시간입니다. (적어도, jblas는 jama보다 2.5 배 빠르며, jama보다 10 배 빠르지 않았습니다.)
— Hugh Perkins

17
방금 netlib-java v1.0을 공개했습니다 ... 성능이 Fortran 코드와 동일합니다 (때로는 능가). 사용자 코드를 변경하지 않고도 머신 최적화 네이티브를 사용할 수 있습니다. 저수준 선형 대수 라이브러리를 찾을 때 이것을 고려하십시오. 또한 netlib-java를 사용하는 MTJ 를 유지 합니다. 스칼라에서는 Breeze (또한 제공 netlib-java)
— fommil을 사용하십시오.

4
ND4j와 java를 사용하면 비교적 오래된 랩탑이 219 밀리 초 안에 제안 된 곱셈을 완료합니다. python + numpy가 349 millis
— bennyl

2
그리고 nd4j 사용에 대한 마지막 의견을 추가하기 위해 네이티브 플랫폼을 백엔드로 사용했습니다. cuda- 플랫폼을 사용하는 경우 약 1 밀리 초가 소요됩니다
— bennyl

벤치 마크 용 코드를 어딘가에 게시 했습니까?
— bruziuz

108

저는 JMatBench (Java Matrix Benchmark)의 저자 이며이 토론에 대해 생각하겠습니다.

Java 라이브러리 간에는 상당한 차이가 있으며 전체 작업 범위에서 확실한 승자는 없지만 최신 성능 결과 에서 볼 수있는 명확한 리더는 거의 없습니다 (2013 년 10 월).

"큰"행렬로 작업하고 기본 라이브러리를 사용할 수있는 경우 시스템 최적화 netlib을 갖춘 MTJ 는 확실한 승자입니다 (약 3.5 배 더 빠름) . 순수한 Java 솔루션이 필요한 경우 MTJ , OjAlgo , EJML 및 Parallel Colt 가 적합합니다. 작은 행렬의 경우 EJML이 확실한 승자입니다.

언급하지 않은 라이브러리는 중요한 성능 문제를 나타내거나 주요 기능이 누락되었습니다.


6
벤치 마크가 정말 편리하다고 언급했습니다! 시간을 내 주셔서 감사합니다.
— hohonuuli

1
JBLAS는 9 월 13 일 현재 SVD를 지원하는 것으로 보입니다 : mikiobraun.github.io/jblas/javadoc/org/jblas/…
— Leopd

훌륭한 작품입니다.
— webpat

평가했지만 라이브러리에 결과를 게시하지 않은 라이브러리 및 그 이유가있는 목록이 있습니까?
— Kevin Krumwiede 님이

1
MTJ는 포기 보인다 : 저장소가 보관하고 마지막은 2016 년에 있었다 커밋
— 다닐라 Piatov을

51

저는 jblas의 주요 저자이며 2009 년 12 월 말에 1.0 버전을 출시했다고 지적하고 싶었습니다. 포장에 많은 노력을 기울였습니다. 이제 ATLAS 및 JNI 라이브러리로 "뚱뚱한 병"을 다운로드 할 수 있습니다. Windows, Linux, Mac OS X, 32 및 64 비트 (Windows 제외). 이런 식으로 jar 파일을 클래스 경로에 추가하여 기본 성능을 얻을 수 있습니다. http://jblas.org 에서 확인하십시오 !


2
작업에서 영감을, 나는에서 비슷한 일했다 NETLIB - 자바를 ;-)
— fommil

2
하하, 나도 jeigen :-)
— 휴 퍼킨스

JogAmp도 동일합니다 (jogamp-fat.jar 참조). 좋은 생각 :)
— gouessej

8

실제로 특정 라이브러리에 대해서는 언급 할 수 없지만 원칙적으로 Java에서 이러한 작업이 느려질 이유는 거의 없습니다. 핫스팟은 일반적으로 컴파일러가 기대하는 종류의 작업을 수행합니다. Java 변수에 대한 기본 수학 연산을 해당 기계 명령어 (SSE 명령어를 사용하지만 연산 당 하나만 사용)로 컴파일합니다. 배열의 요소에 대한 액세스는 "원시"MOV 명령어를 사용하도록 컴파일됩니다. 가능할 때 레지스터에 변수를 할당하는 방법을 결정합니다. 프로세서 아키텍처를 활용하기 위해 명령어의 순서를 바꿉니다. 언급 한 바와 같이 Hotspot은 SSE 명령어 당 하나의 작업 만 수행한다는 점이 예외입니다. 원칙적으로 명령 당 여러 작업을 수행하는 환상적인 최적화 된 매트릭스 라이브러리를 가질 수 있습니다. 예를 들어, 특정 FORTRAN 라이브러리가 그러한 라이브러리를 가지고 있는지 또는 그러한 라이브러리가 존재하는지 여부는 알 수 없습니다. 그렇다면 Java (또는 적어도 Hotspot)와 경쟁 할 수있는 방법이 없습니다 (물론 Java에서 호출하도록 최적화를 사용하여 고유 라이브러리를 작성할 수는 있습니다).

이 모든 것이 무엇을 의미합니까? 잘:

  • 원칙적으로, 더 나은 성능의 라이브러리를 찾는 것이 가치가 있지만 불행히도 나는 그것을 추천 할 수는 없습니다.
  • 성능이 정말 중요하다면, 자신의 매트릭스 연산을 코딩하는 것을 고려할 것입니다. 라이브러리가 일반적으로 할 수없는 특정 최적화 또는 사용하지 않는 특정 라이브러리를 수행 할 수 있기 때문입니다 ( 멀티 프로세서 머신, 라이브러리가 실제로 멀티 스레드인지 확인)

행렬 연산에 방해가되는 경우는 데이터를 서로 정렬하는 순서대로 데이터를 저장해야하기 때문에 행 단위 및 열 단위로 (예 : 행렬 곱셈)를 통과해야하는 경우 발생하는 데이터 지역성 문제입니다. 그러나 코드를 직접 작성하는 경우 연산을 결합하여 데이터 지역성을 최적화 할 수 있습니다 (예 : 변환에 행렬을 곱하는 경우 결합 대신 전용 함수를 작성하면 열 순회를 행 순회로 전환 할 수 있음) 두 개의 라이브러리 함수). 평소와 같이 라이브러리는 더 빠른 개발을 위해 최적의 성능을 제공합니다. 성능이 얼마나 중요한지 결정해야합니다.


8

방금 Apache Commons Math와 jlapack을 비교했습니다.

테스트 : 임의의 1024x1024 매트릭스의 특이 값 분해.

머신 : Intel (R) Core (TM) 2 Duo CPU E6750 @ 2.66GHz, Linux x64

옥타브 코드 : A = rand (1024); 틱; [U, S, V] = svd (A); toc

결과 실행 시간
-------------------------------------------------- -------
옥타브 36.34 초

JDK 1.7u2 64 비트
    jlapack dgesvd 37.78 초
    Apache Commons Math SVD 42.24 초


JDK 1.6u30 64 비트
    jlapack dgesvd 48.68 초
    Apache Commons Math SVD 50.59 초

기본 루틴
C에서 호출 된 Lapack * : 37.64 초
인텔 MKL 6.89 초 (!)

내 결론은 JDK 1.7에서 호출 된 jlapack이 lapack의 기본 이진 성능에 매우 가깝다는 것입니다. 리눅스 배포판과 함께 제공되는 lapack 바이너리 라이브러리를 사용하고 dgesvd 루틴을 호출하여 U, S 및 VT 행렬도 가져 왔습니다. 모든 테스트는 매번 정확히 동일한 매트릭스에서 배정 밀도를 사용하여 수행되었습니다 (옥타브 제외).

면책 조항-나는 선형 대수학의 전문가가 아니며 위의 라이브러리와 관련이 없으며 엄격한 벤치 마크가 아닙니다. JDK 1.7에서 1.6으로의 성능 향상뿐만 아니라 commons math SVD에서 jlapack으로의 비교에 관심이 있었기 때문에 '집에서 만든'테스트입니다.


8

지겐 https://github.com/hughperkins/jeigen

  • 가장 빠른 무료 C ++ 라이브러리 중 하나 인 Eigen C ++ 라이브러리 http://eigen.tuxfamily.org 포장
  • 비교적 간결한 구문, 예 : 'mmul', 'sub'
  • 고밀도 및 희소 행렬 모두 처리

두 개의 고밀도 매트릭스를 곱한 빠른 테스트 :

정적 jeigen.MatrixUtil. * 가져 오기

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
  • 자마에 비해 모든 것이 더 빠릅니다 :-P
  • jigen에 비해 Jeigen은 그리 빠르지는 않지만 희소 행렬을 처리합니다.
  • ojalgo와 비교하여 Jeigen은 경과 시간이 거의 동일하지만 하나의 코어 만 사용하므로 Jeigen은 전체 CPU의 절반을 사용합니다. Jeigen은 더 간결한 구문을 가지고 있습니다.

Jeigen은 굉장해 보인다! 최근에 JNI와 DLL을 사용하여 매우 큰 희소 행렬을 해결하기 위해 Eigen을 Java로 구현했습니다. DLL이있는 내 버전은 테스트 (8000x8000 행렬 이상)의 병렬 콜트보다 20 이상 빠릅니다. 나는 Jeigen에 대해 알고 있었으면 좋겠다!
— Z boson

6

몇 가지 다른 하드웨어 구성을 위해 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 라이브러리였습니다.


4

나는 ~의 저자입니다 la4j (Linear Algebra for Java) 라이브러리 이며 여기에 내 요점이 있습니다. 3 년 동안 la4j를 작업 해 왔으며 (최신 릴리스는 0.4.0 [2013 년 6 월 1 일]) 이제 최소한의 필수 기능 만 다루었으므로 성능 분석 및 최적화를 시작할 수 있습니다. 그래서 la4j는 내가 원하는만큼 빠르지 않지만 그것을 바꾸는 데 많은 시간을 소비하고 있습니다.

현재 la4j의 새 버전을 JMatBench 플랫폼 으로 이식하는 중입니다 . la4j에서 훨씬 빠른 내부 행렬 형식, 안전하지 않은 접근 자 및 행렬 곱셈을위한 빠른 차단 알고리즘과 같은 몇 가지 개선 사항이 있기 때문에 새 버전이 이전 버전보다 더 나은 성능을 발휘하기를 바랍니다.


1
아니오-la4j는 실제로 경쟁이 없습니다. 참조 code.google.com/p/java-matrix-benchmark
— 크리스토퍼 매닝에게

많이 바뀌 었습니다. 귀하의 답변 이후 두 가지 버전의 라이브러리를 출시했습니다. 현재 릴리스는 0.4.0입니다. 그리고 그냥 날아갑니다.
— 블라디미르 코스 튜 코프

3

Pentiums 및 이후 프로세서의 벡터 컴퓨팅 기능 (LAPACK 및 현재 Atlas BLAS와 같은 MMX 확장으로 시작)에 크게 의존하는 Linalg 코드는 "환상적으로 최적화 된"것이 아니라 단순히 업계 표준입니다. Java에서 그 성능을 복제하려면 기본 라이브러리가 필요합니다. 나는 당신이 묘사 한 것과 같은 성능 문제를 겪었으며 (주로 Choleski 분해를 계산할 수 있음) 실제로 효율적인 것을 발견하지 못했습니다 .Jama는 구현자가 따라야 할 템플릿 및 참조 키트이기 때문에 순수한 Java입니다. .. 결코 일어나지 않았다. 아파치 수학의 공통점을 알고 있습니다. COLT는 아직 테스트를 해보았지만 닌자 개선에 크게 의존하는 것 같습니다. 대부분은 애드혹 Java 컴파일러를 구축하여 도달 한 것이므로 도움이 될 것 같지는 않습니다. 그 시점에서 우리는 "


좋은 지적! : JNI와 알파 단계 프로젝트는 아틀라스의 래퍼 jblas.org . 작성자의 블로그 게시물 : mikiobraun.blogspot.com/2008/10/…
— dfrankow

3

우리는 꽤 큰 심각한 재무 계산에 COLT를 사용했으며 그 결과에 매우 만족했습니다. 심하게 프로파일 링 된 코드에서 우리는 COLT 구현을 우리의 것으로 대체 할 필요가 거의 없었습니다.

자체 테스트에서 (분명히 독립적이지 않음) 인텔이 직접 최적화 한 어셈블러 루틴의 2 요소 내에서 주장한다고 생각합니다. 잘 사용하는 비결은 디자인 철학을 이해하고 불필요한 객체 할당을 피하는 것입니다.


3

인텔 수학 커널 라이브러리를 살펴 보셨습니까 ? ATLAS 보다 성능이 우수하다고 주장합니다 . MKL은 JNI 래퍼를 통해 Java에서 사용할 수 있습니다 .


2
우리는 그것을 가지고 있습니다. a) 라이센스가 Atlas보다 제한적이므로 모든 컴퓨터를 사용할 수는 없습니다. b) Java가 아닙니다 (그리고 우리가 Java에 있기를 원하는 이유가 있다고 말했듯이).
— dfrankow

즉, 이것은 Java 라이브러리에 대한 내 질문에 대한 답변이 아닙니다 (그러나 그것을 공감 할 평판은 없습니다).
— dfrankow

@ dfrankow : Java에서 사용하는 것에 대한 귀하의 우려를 해결하기 위해 답변을 업데이트했습니다.
— Zach Scrivena

1
+1, 만약 당신이 찾고있는 속도라면, 이것이가는 길인 것 같습니다
— Gab Royer

2
마지막 링크가 끊어졌습니다.
— gouessej


2

jblas 프로젝트 를 확인하고 싶을 수도 있습니다 . 고성능 매트릭스 작업에 BLAS, LAPACK 및 ATLAS를 사용하는 비교적 새로운 Java 라이브러리입니다.

개발자는 jblas가 MTJ 및 Colt에 유리하게 나오는 벤치 마크 를 게시했습니다 .


2

3d 그래픽스 응용 프로그램의 경우 lwjgl.util 벡터 구현은 위에서 언급 한 jblas보다 약 3 배나 성능이 우수합니다.

4x4 행렬로 vec4에 백만 개의 행렬 곱셈을 수행했습니다.

lwjgl은 약 18ms로 완료되었으며 jblas는 약 60ms가 필요했습니다.

(JNI 접근법은 상대적으로 작은 곱셈의 빠른 연속 적용에는 적합하지 않다고 가정합니다. 변환 / 매핑은 곱셈의 실제 실행보다 시간이 오래 걸릴 수 있기 때문입니다.)


1

고차원 행렬을 많이 만드는 경우 2 차원 배열 대신 단일 차원 배열을 사용하도록 Jama를 변경하면 Jama를 약 20 % 더 빠르게 만들 수 있습니다. Java가 다차원 배열을 효율적으로 지원하지 않기 때문입니다. 즉. 배열 배열을 만듭니다.

콜트는 이미 이것을하고 있지만, 콜트에서는 단순한 기능이 왜 느린 지 설명 할 수있는 자마보다 더 복잡하고 강력하다는 것을 알았습니다.

대답은 실제로 당신이하고있는 것에 달려 있습니다. Jama는 Colt가 할 수있는 일 중 일부를 지원하여 더 많은 차이를 만들지 않습니다.



0

자유롭게 사용할 수있는 다양한 Java 선형 대수 라이브러리가 있습니다. http://www.ujmp.org/java-matrix/benchmark/ 불행하게도이 벤치 마크에서는 행렬 곱셈에 대한 정보 만 제공합니다 (테스트를 바꿈으로써 다른 라이브러리가 각각의 디자인 기능을 이용할 수는 없음).

살펴보아야 할 것은 이러한 선형 대수 라이브러리가 다양한 행렬 분해 계산을 요청받을 때 어떻게 수행되는지입니다. http://ojalgo.org/matrix_compare.html


0

MTJ (Matrix Tookits Java)는 이전에 이미 언급되었지만 다른 사람이이 스레드를 다루는 경우 다시 언급 할 가치가 있습니다. 관심있는 사람들에게는 MTJ가 아파치 커먼즈 math 2.0 의 linalg 라이브러리를 대체하는 것에 대해 이야기하는 것처럼 보이지만 최근에는 어떻게 진행되고 있는지 잘 모르겠습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.