2011-12-22 2 views
2

GPU의 CUDA 또는 OpenCL 코드의 병렬성에 대한 일반적인 질문이 있습니다. 나는 NVIDIA GTX 470을 사용합니다.GPU의 병렬 처리 - CUDA/OpenCL

나는 Cuda 프로그래밍 가이드에서 간략하게 읽었지만 여기에서 묻는 관련 답변을 찾지 못했습니다.

저는 CUDA 커널을 호출하는 최상위 함수를 가지고 있습니다 (같은 커널의 경우 OpenCL 버전이 있습니다). 이 최상위 함수는 3 개의 다른 데이터 세트 (이미지 데이터 R, G, B) 에 대해 내 주요 기능에서 'for 루프'로 3 번 호출되며 실제 코드 렛은 이미지/프레임에 2 'for loops'가 있습니다.

내가 알고 싶은 것은 여기에서 어떤 종류의 병렬 처리가 활용되는지입니다 - 작업 수준 병렬 처리 또는 데이터 병렬 처리?

그래서이 CUDA와 C 코드는 코드 렛과 최상위 코드의 여러 기능/기능에 대한 다중 스레드를 만들고 병렬로 실행하고 작업 병렬 처리를 사용합니다. 그렇다면 누가 명시 적으로 코드에 포함되어 있거나 링크 된 스레딩 라이브러리가 없으므로 누가 그것을 작성합니다.

OR

이것은 독립되므로 데이터 병렬성을 달성하고 반복 '루프'에 대한 다른 스레드/태스크를 생성한다. 이러한 종류의 병렬 처리를 수행하는 경우, for 루프 반복마다 다른 종속성이 없으므로 병렬로 예약 할 수 있다는 점을 참고하여이를 악용합니까?

컴파일러/스케줄러에게 루프/함수를 병렬로 예약하도록 지시하는 특수 컴파일러 생성자/내장 함수 (openMP와 같은 병렬 루프)가 표시되지 않으므로?

모든 독서 자료가 도움이 될 것입니다.

답변

4

GPU에서의 병렬 처리는 SIMT (단일 명령어 다중 스레드)입니다. CUDA 커널의 경우 모든 블록에 N 개의 스레드가있는 블록 그리드를 지정합니다. CUDA 라이브러리는 모든 트릭을 수행하고 CUDA 컴파일러 (nvcc)는 GPU 코드를 생성합니다. 마녀는 GPU에 의해 실행됩니다. CUDA lib는 GPU 드라이버와 GPU의 스레드 스케줄러에게 커널을 실행할 스레드 수 ((블록 수) x (스레드 수))를 알려줍니다. 귀하의 예제에서 최상위 함수 (또는 호스트 함수)는 비동기 적이며 emediatly를 반환하는 커널 호출 만 실행합니다. nvcc가 드라이버 호출을 작성하기 때문에 스레딩 라이브러리가 필요하지 않습니다.

샘플 커널 호출은 다음과 같습니다

helloworld<<<BLOCKS, THREADS>>>(/* maybe some parameters */); 

의 OpenCL이 같은 패러다임을 다음하지만 (그들은 미리 컴파일되지 않은 경우) 런타임에을 yor 커널을 컴파일합니다. 커널을 실행할 스레드 수를 지정하면 lib가 나머지를 수행합니다.

CUDA (OpenCL을)를 배울 수있는 가장 좋은 방법은 CUDA Programming Guide (OpenCL Programming Guide) 살펴보고 GPU Computing SDK의 샘플 보는 것입니다.

2

제가 알고 싶은 것은 여기에 어떤 종류의 병렬 처리가 사용되는지입니다 - 작업 수준 병렬 처리 또는 데이터 병렬 처리?

데이터 병렬 처리가 우세하지만 일부 병렬 처리도 포함됩니다.

이미지 처리 예제에서 커널은 단일 출력 픽셀에 대한 처리를 수행 할 수 있습니다. OpenCL 또는 CUDA에게 출력 이미지의 픽셀만큼 많은 스레드를 실행하도록 지시합니다. 그런 다음 해당 스레드를 대상 GPU/CPU에서 실행되도록 예약합니다.

고도의 병렬 데이터. 커널은 하나의 작업 항목을 작성하도록 작성되었으며 수백만 개의 작업 항목을 계획합니다.

호스트 프로그램이 여전히 모든 스레드를 실행하는 GPU 반면 CPU에서 실행되고, 그래서 다른 작업과 함께 승차 할 수 있기 때문에 작업의 병렬 처리에 온다. 종종 이것은 다음 커널 스레드 세트에 대한 데이터를 준비하는 것이지만 완전히 별개의 작업이 될 수 있습니다.

2

여러 커널을 실행하면 자동으로 병렬 처리되지 않습니다 (즉, GPU 작업 병렬 처리 없음). 그러나 커널 호출은 호스트 측에서 비동기 적이므로 호스트 코드는 커널이 실행되는 동안 계속해서 병렬로 실행됩니다.

작업 병렬 처리를 수행하려면 Cuda에서 개념을 스트림이라고하며 OpenCL 명령 대기열에 넣어야합니다. 명시 적으로 여러 스트림/대기열을 만들고 각 대기열에 대해 각 커널을 예약하지 않으면 대기열이 순서대로 실행될 수있는 OpenCL 기능이 있지만 구현을 지원하는지 여부는 알 수 없습니다.) 그러나 커널을 병렬로 실행하면 각 데이터 세트가 모든 GPU 코어를 활용할만큼 충분히 큰 경우별로 도움이되지 않습니다.

커널에서 실제 루프가있는 경우 자체적으로 병렬 처리되지는 않습니다. 병렬 처리는 그리드 크기를 지정하여 커널이 해당 그리드의 각 요소에 대해 병렬로 호출되도록합니다 (if 당신은 커널 내부에 for 루프를 갖고 있으며, 그들은 각 스레드에 의해 전체 에서 실행될 것이다. 다시 말해, 커널을 호출 할 때 그리드 크기를 지정해야하며, 커널 내부에서 threadIdx/blockIdx (Cuda) 또는 getGlobalId() (OpenCL)를 사용하여 특정 스레드에서 처리 할 데이터 항목을 식별하십시오.

OpenCL을 배우기위한 유용한 책은 OpenCL Programming Guide이지만 OpenCL spec도 살펴볼 가치가 있습니다.