AMD Radeon HD 7800 시리즈 GPU와 함께 사용할 OpenCL 프로그램을 작성 중입니다. AMD의 OpenCL 프로그래밍 가이드 에 따르면 ,이 세대의 GPU에는 비동기 적으로 작동 할 수있는 두 개의 하드웨어 대기열이 있습니다.
5.5.6 명령 대기열
남섬 및 그 이후의 장치는 최소한 두 개의 하드웨어 계산 대기열을 지원합니다. 이를 통해 응용 프로그램은 비동기 제출 및 실행을 위해 두 개의 명령 대기열로 소규모 디스패치의 처리량을 증가시킬 수 있습니다. 하드웨어 계산 대기열은 다음 순서로 선택됩니다. 첫 번째 대기열 = 짝수 OCL 명령 대기열, 두 번째 대기열 = 홀수 OCL 대기열.
이를 위해 GPU에 데이터를 공급하기 위해 두 개의 별도 OpenCL 명령 대기열을 만들었습니다. 대략 호스트 스레드에서 실행되는 프로그램 은 다음과 같습니다.
static const int kNumQueues = 2;
cl_command_queue default_queue;
cl_command_queue work_queue[kNumQueues];
static const int N = 256;
cl_mem gl_buffers[N];
cl_event finish_events[N];
clEnqueueAcquireGLObjects(default_queue, gl_buffers, N);
int queue_idx = 0;
for (int i = 0; i < N; ++i) {
cl_command_queue queue = work_queue[queue_idx];
cl_mem src = clCreateBuffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, ...);
// Enqueue a few kernels
cl_mem tmp1 = clCreateBuffer(CL_READ_WRITE);
clEnqueueNDRangeKernel(kernel1, queue, src, tmp1);
clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp1);
cl_mem tmp2 = clCreateBuffer(CL_READ_WRITE);
clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp2);
clEnqueueNDRangeKernel(kernel3, queue, tmp2, gl_buffer[i], finish_events + i);
queue_idx = (queue_idx + 1) % kNumQueues;
}
clEnqueueReleaseGLObjects(default_queue, gl_buffers, N);
clWaitForEvents(N, finish_events);
을 사용 kNumQueues = 1
하면이 응용 프로그램은 의도 한대로 작동합니다. 모든 작업을 단일 명령 대기열로 수집 한 다음 GPU가 전체 시간 동안 상당히 바쁠 때까지 완료됩니다. CodeXL 프로파일 러의 출력을 보면 이것을 볼 수 있습니다.
그러나을 설정 kNumQueues = 2
하면 동일한 일이 발생할 것으로 예상되지만 작업이 두 대기열에 균등하게 분할됩니다. 어쨌든 각 큐는 하나의 큐와 개별적으로 동일한 특성을 갖기를 기대합니다. 모든 것이 완료 될 때까지 순차적으로 작동하기 시작합니다. 그러나 두 개의 대기열을 사용할 때 모든 작업이 두 개의 하드웨어 대기열에 분할되는 것은 아닙니다.
GPU 작업이 시작될 때 대기열은 일부 커널을 비동기식으로 실행하도록 관리하지만 하드웨어 대기열을 완전히 차지하지는 않습니다 (내 이해가 잘못되지 않는 한). GPU 작업이 끝날 무렵 대기열이 하드웨어 대기열 중 하나에 만 순차적으로 작업을 추가하는 것처럼 보이지만 커널이 실행되지 않는 경우가 있습니다. 무엇을 제공합니까? 런타임 작동 방식에 대한 근본적인 오해가 있습니까?
왜 이런 일이 일어나고 있는지에 대한 몇 가지 이론이 있습니다.
산재 된
clCreateBuffer
호출로 인해 GPU가 공유 메모리 풀에서 장치 리소스를 동 기적으로 할당하여 개별 커널 실행을 중단시킵니다.기본 OpenCL 구현은 논리적 대기열을 물리적 대기열에 매핑하지 않으며 런타임에 객체를 배치 할 위치 만 결정합니다.
GL 객체를 사용하고 있기 때문에 GPU는 쓰기 중에 특별히 할당 된 메모리에 대한 액세스를 동기화해야합니다.
이러한 가정 중 하나라도 사실입니까? 누구나 2 큐 시나리오에서 GPU가 대기하는 원인을 알고 있습니까? 모든 통찰력에 감사드립니다!