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

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

사람들은 행렬 수학 (예 : 곱하기, 역함수)을위한 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는 훨씬 느리지 않고 때로는 훨씬 빠릅니다.



답변

내 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는 빠르지 않습니다.


답변

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

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

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

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


답변

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


답변

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

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

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

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


답변

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

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

머신 : 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으로의 비교에 관심이 있었기 때문에 ‘집에서 만든’테스트입니다.


답변

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

답변

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