우선, CUDA가 자동 계산을 더 빠르게하지 않을 것이라는 사실을 알고 있어야합니다. GPU 프로그래밍은 예술이기 때문에 한편으로, 그것은 매우 그걸 얻기 위해 도전, 매우 될 수있다 권리 . 반면에 GPU는 특정 종류 의 계산 에만 적합하기 때문 입니다.
기본적으로 GPU에서 모든 것을 계산할 수 있기 때문에 혼동 될 수 있습니다 . 물론 핵심은 좋은 속도 향상 여부를 결정하는 것입니다. 여기서 가장 중요한 분류는 문제가 작업 병렬 인지 데이터 병렬인지 입니다. 첫 번째는 대략적으로 말하면 여러 스레드가 자체 작업을 다소 독립적으로 수행하는 문제를 나타냅니다. 두 번째는 많은 스레드가 모두 동일 하지만 데이터의 다른 부분에서 수행하는 문제를 나타냅니다 .
후자는 GPU가 잘하는 종류의 문제입니다. GPU에는 많은 코어가 있으며 모든 코어는 동일하지만 입력 데이터의 다른 부분에서 작동합니다.
당신은 "간단한 수학이지만 엄청난 양의 데이터"를 가지고 있다고 언급했습니다. 이것은 완벽하게 데이터 병렬 문제처럼 들리므로 GPU에 적합하다고 생각할 수도 있지만 고려해야 할 또 다른 측면이 있습니다 .GPU는 이론적 계산 능력 (FLOPS, 초당 부동 소수점 연산) 측면에서 엄청나게 빠릅니다. 그러나 이들은 종종 메모리 대역폭에 의해 제한됩니다.
이것은 또 다른 분류 문제로 이어진다. 즉, 문제가 메모리 바운드 인지 계산 바운드 인지 여부 입니다.
첫 번째는 각 데이터 요소에 대해 수행되는 명령 수가 적은 문제를 나타냅니다. 예를 들어, 병렬 벡터 덧셈을 고려하십시오. 두 개의 데이터 요소 를 읽은 다음 한 번의 덧셈을 수행 한 다음 합계를 결과 벡터에 써야 합니다. 단일 추가는 메모리 읽기 / 쓰기 노력을 보상하지 않기 때문에 GPU에서이 작업을 수행 할 때 속도가 향상되지 않습니다.
두 번째 용어 인 "컴퓨 트 바운드"는 메모리 읽기 / 쓰기 수에 비해 명령어 수가 많은 문제를 나타냅니다. 예를 들어, 행렬 곱셈을 고려하십시오. n이 행렬의 크기 인 경우 명령어 수는 O (n ^ 3)입니다. 이 경우 GPU가 특정 매트릭스 크기에서 CPU보다 성능이 우수 할 것으로 예상 할 수 있습니다. 또 다른 예는 "복수의"데이터 요소에 대해 많은 복잡한 삼각법 계산 (사인 / 코사인 등)이 수행되는 경우입니다.
경험적으로 "메인"GPU 메모리에서 하나의 데이터 요소를 읽거나 쓰는 데 약 500 개의 명령 대기 시간이 있다고 가정 할 수 있습니다 ....
따라서 GPU 성능의 또 다른 핵심 요점은 데이터 지역성입니다 . 데이터 를 읽거나 써야하는 경우 (대부분의 경우 ;-)해야 함) 데이터를 최대한 가깝게 유지하십시오 GPU 코어에 가능합니다. 따라서 GPU는 일반적으로 크기가 몇 KB에 불과하지만 계산에 관련된 데이터에 특히 효율적인 특정 메모리 영역 ( "로컬 메모리"또는 "공유 메모리"라고 함)을 갖습니다.
다시 강조하자면 : GPU 프로그래밍은 예술이며 CPU에서의 병렬 프로그래밍과 만 관련이 있습니다. 같은 모든 동시성 인프라 자바 스레드 같은 것들, ThreadPoolExecutors
, ForkJoinPools
등 그냥 어떻게 든 작업을 분할하고 여러 프로세서들에게 배포해야한다는 인상을 줄 수 있습니다. GPU에서는 점유, 등록 압력, 공유 메모리 압력, 메모리 통합 등과 같은 훨씬 낮은 수준의 문제가 발생할 수 있습니다.
그러나 해결해야 할 데이터 병렬 컴퓨팅 바운드 문제가있는 경우 GPU를 사용하는 것이 좋습니다.
일반적인 언급 : CUDA를 구체적으로 요청했습니다. 그러나 OpenCL도 살펴 보는 것이 좋습니다. 몇 가지 장점이 있습니다. 우선, 벤더 독립적 인 개방형 산업 표준이며 AMD, Apple, Intel 및 NVIDIA의 OpenCL 구현이 있습니다. 또한 Java 세계에서 OpenCL에 대한 훨씬 광범위한 지원이 있습니다. CUDA에 대해 해결하려는 유일한 경우는 FFT 용 CUFFT 또는 BLAS (매트릭스 / 벡터 연산) 용 CUBLAS와 같은 CUDA 런타임 라이브러리를 사용하려는 경우입니다. OpenCL에 유사한 라이브러리를 제공하는 방법이 있지만 이러한 라이브러리에 대한 고유 한 JNI 바인딩을 작성하지 않으면 Java 측에서 직접 사용할 수 없습니다.
또한 2012 년 10 월 OpenJDK HotSpot 그룹이 "Sumatra"프로젝트를 시작했다고 들었습니다 : http://openjdk.java.net/projects/sumatra/ . 이 프로젝트의 목표는 JVM에서 직접 GPU 지원을 제공 하고 JIT의 지원을 제공하는 것입니다. 현재 상태와 첫 번째 결과는 http://mail.openjdk.java.net/mailman/listinfo/sumatra-dev 의 메일 링리스트에서 확인할 수 있습니다 .
그러나 얼마 전 저는 일반적으로 "Java on the GPU"와 관련된 리소스를 수집했습니다. 여기서는 특별한 순서없이 여기에 다시 요약하겠습니다.
( 면책 조항 : 저는 http://jcuda.org/ 및 http://jocl.org/ 의 저자입니다 )
(바이트) 코드 변환 및 OpenCL 코드 생성 :
https://github.com/aparapi/aparapi : AMD가 만들고 적극적으로 관리하는 오픈 소스 라이브러리입니다. 특수한 "Kernel"클래스에서는 병렬로 실행해야하는 특정 메소드를 대체 할 수 있습니다. 이 메소드의 바이트 코드는 런타임에 자체 바이트 코드 리더를 사용하여로드됩니다. 코드는 OpenCL 코드로 변환 된 다음 OpenCL 컴파일러를 사용하여 컴파일됩니다. 그런 다음 GPU 또는 CPU 일 수있는 OpenCL 장치에서 결과를 실행할 수 있습니다. OpenCL로 컴파일 할 수 없거나 OpenCL을 사용할 수없는 경우에도 스레드 풀을 사용하여 코드가 병렬로 실행됩니다.
https://github.com/pcpratts/rootbeer1 : Java의 일부를 CUDA 프로그램으로 변환하기위한 오픈 소스 라이브러리. 특정 클래스가 GPU에서 실행되어야 함을 나타 내기 위해 구현 될 수있는 전용 인터페이스를 제공합니다. Aparapi와 달리 "관련"데이터 (즉, 객체 그래프의 전체 관련 부분!)를 GPU에 적합한 표현으로 자동 직렬화하려고 시도합니다.
https://code.google.com/archive/p/java-gpu/ : 주석이 달린 Java 코드 (일부 제한이 있음)를 CUDA 코드로 변환하기위한 라이브러리이며,이 코드는 GPU에서 코드를 실행하는 라이브러리로 컴파일됩니다. 라이브러리는 PhD 논문의 맥락에서 개발되었으며 번역 프로세스에 대한 심도있는 배경 정보가 포함되어 있습니다.
https://github.com/ochafik/ScalaCL : OpenCL에 대한 스칼라 바인딩. 특수 스칼라 컬렉션을 OpenCL과 병렬로 처리 할 수 있습니다. 컬렉션의 요소에서 호출되는 함수는 일반적인 스칼라 함수 (일부 제한 있음) 일 수 있으며 OpenCL 커널로 변환됩니다.
언어 확장
http://www.ateji.com/px/index.html : 병렬 구조 (예 : 병렬 for 루프, OpenMP 스타일)를 허용하는 Java 용 언어 확장으로 OpenCL을 사용하여 GPU에서 실행됩니다. 불행히도이 유망한 프로젝트는 더 이상 유지되지 않습니다.
http://www.habanero.rice.edu/Publications.html (JCUDA) : 특수 Java 코드 (JCUDA 코드)를 Java 및 CUDA-C 코드로 변환하여 컴파일 및 실행할 수있는 라이브러리 GPU. 그러나이 라이브러리는 공개적으로 사용할 수없는 것 같습니다.
https://www2.informatik.uni-erlangen.de/EN/research/JavaOpenMP/index.html : CUDA 백엔드가있는 OpenMP 구성을위한 Java 언어 확장
Java OpenCL / CUDA 바인딩 라이브러리
https://github.com/ochafik/JavaCL : OpenCL에 대한 Java 바인딩 : 자동 생성 된 저수준 바인딩을 기반으로하는 객체 지향 OpenCL 라이브러리
http://jogamp.org/jocl/www/ : OpenCL에 대한 Java 바인딩 : 자동 생성 된 저수준 바인딩을 기반으로하는 객체 지향 OpenCL 라이브러리
http://www.lwjgl.org/ : OpenCL을위한 Java 바인딩 : 자동 생성 된 저수준 바인딩 및 객체 지향 편의 클래스
http://jocl.org/ : OpenCL에 대한 Java 바인딩 : 원래 OpenCL API의 1 : 1 맵핑 인 저수준 바인딩
http://jcuda.org/ : CUDA를위한 Java 바인딩 : 원래 CUDA API의 1 : 1 매핑 인 저수준 바인딩
여러 가지 잡다한
http://sourceforge.net/projects/jopencl/ : OpenCL에 대한 Java 바인딩. 2010 년 이후 더 이상 유지되지 않는 것 같습니다
http://www.hoopoe-cloud.com/ : CUDA를위한 Java 바인딩. 더 이상 유지되지 않는 것 같습니다