2013-05-04 1 views
3

OpenCL을 사용하여 솔루션을 구현 중입니다. 예를 들어 GPU에 한 번 복사 할 많은 양의 데이터가 있고 다음과 같이 많은 커널 프로세스가 필요합니다. 일괄 처리하고 특정 출력 버퍼에 결과를 저장합니다.OpenCL Copy-Once 많이 공유하십시오.

실제 질문은 어떤 방법으로 더 빠릅니까? 동일한 커널을 (동일한 문맥에서) 처리하기 전에 필요한 배열의 일부분을 각 커널에 대기 시키거나 동일한 배열을 전달해야합니다. 동일한 주소 공간을 가지며 각각의 커널을 매핑 할 수 있기 때문입니다 동시에 배열. 물론 배열은 읽기 전용이지만 커널을 실행할 때마다 변하지 않기 때문에 일정하지 않습니다 ... (그래서 전역 메모리 버퍼를 사용하여 캐시 할 수 있습니다).

또한 두 번째 방법이 실제로 더 빠르면 실제로 구현할 수있는 방법을 찾지 못했지만 (아직 검색 중이지만 :) :).

건배.

+0

쿠다 태그를 제거 –

+0

예, 죄송합니다. – jtimz

답변

2

정상적으로 두 번째 메모리를 사용합니다. 기억을 공유하는 것은 쉽습니다. 각 커널에 동일한 버퍼를 전달하십시오. 내 실시간 광선 추적기에서이 작업을 수행합니다. 나는 하나의 커널과 포스트 프로세스 (이미지 프로세스)를 다른 커널로 렌더링한다. 는 C++ 바인딩을 사용

는 당신이 하나의 커널이 배열/메모리의 다른 부분에서 작동하려면

cl_input_mem = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_uchar4)*npixels, NULL, &err); 

kernel_render.setArg(0, cl_input_mem); 
kernel_postprocess.setArg(0, cl_input_mem); 

커널 인수에 오프셋 값을 전달하고 해당를 추가 할 수 있습니다 다음과 같이 보입니다 예 각 커널에 대한 전역 메모리 포인터.

배열 (실제로 각 버퍼의 합계 - 출력 포함)이 메모리에 맞지 않으면 첫 번째 방법을 사용합니다. 첫 번째 방법을 사용하는 또 다른 이유는 여러 장치에서 실행중인 경우입니다. 레이 트레이서에서는 여러 장치에서 렌더링 할 때 첫 번째 방법을 사용합니다. 예를 들어, 하나의 GTX 580은 스크린의 상반부를 렌더링하고 다른 GTX 580은 하반부를 렌더링합니다 (사실 이것은 하나의 장치가 30 %를 렌더링 할 수 있으므로 실제로 동적으로 수행하므로 나머지 70 %가 렌더링되지만 점은 제외). 각 장치는 출력의 일부만 렌더링 한 다음 CPU에서 출력을 어셈블합니다. PCI 3.0을 사용하면 CPU와 GPU (여러 번) 사이에서 앞뒤로 전송하면 1920x1080 이미지의 경우에도 프레임 속도에 거의 영향을 미치지 않습니다.

+0

나는 너를 아직 올리 지 못해, 너는 rep> = 15> jtimz

+1

나는 그를 당신을 위해 upvoted;) – Trax

+0

그냥 의견 : 전송 문제 중 하나는 버퍼가 잠겨 있다는 것입니다. 더블 버퍼링을 사용하면 약간 더 나은 성능을 얻을 수 있습니다. – Trax

관련 문제